This commit is contained in:
28
.vscode/launch.json
vendored
Normal file
28
.vscode/launch.json
vendored
Normal file
@@ -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}"
|
||||
}
|
||||
]
|
||||
}
|
||||
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"editor.codeLens": true
|
||||
}
|
||||
15
.vscode/tasks.json
vendored
Normal file
15
.vscode/tasks.json
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"taskName": "build",
|
||||
"command": "dotnet",
|
||||
"type": "process",
|
||||
"args": [
|
||||
"build",
|
||||
"${workspaceFolder}/raven-integration.csproj"
|
||||
],
|
||||
"problemMatcher": "$msCompile"
|
||||
}
|
||||
]
|
||||
}
|
||||
13
ApiResponse.cs
Normal file
13
ApiResponse.cs
Normal file
@@ -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
|
||||
13
ApiTextResponse.cs
Normal file
13
ApiTextResponse.cs
Normal file
@@ -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
|
||||
182
Attachments/AttachmentTest.cs
Normal file
182
Attachments/AttachmentTest.cs
Normal file
@@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// test attach CRUD
|
||||
/// </summary>
|
||||
[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>();
|
||||
long lTestZipAttachmentId = a.ObjectResponse["data"][1]["id"].Value<long>();
|
||||
|
||||
//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<string>();
|
||||
|
||||
//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);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// test no rights
|
||||
/// </summary>
|
||||
[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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// test not attachable
|
||||
/// </summary>
|
||||
[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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// test bad object values
|
||||
/// </summary>
|
||||
[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
|
||||
36
Authentication/Auth.cs
Normal file
36
Authentication/Auth.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using Xunit;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using FluentAssertions;
|
||||
|
||||
namespace raven_integration
|
||||
{
|
||||
|
||||
public class Auth
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[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
|
||||
|
||||
26
AutoId.cs
Normal file
26
AutoId.cs
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
36
AyaType/AyaType.cs
Normal file
36
AyaType/AyaType.cs
Normal file
@@ -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
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[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<long>().Should().Be(2);
|
||||
a.ObjectResponse["data"][2]["name"].Value<string>().Should().Be("Widget [Attachable]");
|
||||
|
||||
}
|
||||
|
||||
|
||||
//==================================================
|
||||
|
||||
}//eoc
|
||||
}//eons
|
||||
176
DataFilter/DataFilterCrud.cs
Normal file
176
DataFilter/DataFilterCrud.cs
Normal file
@@ -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
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Test all CRUD routes
|
||||
/// </summary>
|
||||
[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<long>();
|
||||
|
||||
|
||||
//RETRIEVE
|
||||
//Get one
|
||||
a = await Util.GetAsync("DataFilter/" + Id.ToString(), await Util.GetTokenAsync("BizAdminFull"));
|
||||
Util.ValidateDataReturnResponseOk(a);
|
||||
a.ObjectResponse["data"]["name"].Value<string>().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<string>().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<uint>();
|
||||
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<string>().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);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[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");
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[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");
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[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
|
||||
6237
DataFilter/DataFilterFilteringLists.cs
Normal file
6237
DataFilter/DataFilterFilteringLists.cs
Normal file
File diff suppressed because it is too large
Load Diff
439
DataFilter/DataFilterOrderBy.cs
Normal file
439
DataFilter/DataFilterOrderBy.cs
Normal file
@@ -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
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[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<long>();
|
||||
|
||||
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<long>();
|
||||
|
||||
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<long>();
|
||||
|
||||
|
||||
//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<long>();
|
||||
|
||||
//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<long>().Should().Be(FirstInOrderWidgetId);
|
||||
a.ObjectResponse["data"][1]["id"].Value<long>().Should().Be(SecondInOrderWidgetId);
|
||||
a.ObjectResponse["data"][2]["id"].Value<long>().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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[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<long>();
|
||||
|
||||
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<long>();
|
||||
|
||||
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<long>();
|
||||
|
||||
|
||||
//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<long>();
|
||||
|
||||
//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<long>().Should().Be(FirstInOrderWidgetId);
|
||||
a.ObjectResponse["data"][1]["id"].Value<long>().Should().Be(SecondInOrderWidgetId);
|
||||
a.ObjectResponse["data"][2]["id"].Value<long>().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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[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<long>();
|
||||
|
||||
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<long>();
|
||||
|
||||
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<long>();
|
||||
|
||||
|
||||
//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<long>();
|
||||
|
||||
//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<long>().Should().Be(FirstInOrderWidgetId);
|
||||
a.ObjectResponse["data"][1]["id"].Value<long>().Should().Be(SecondInOrderWidgetId);
|
||||
a.ObjectResponse["data"][2]["id"].Value<long>().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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[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<long>();
|
||||
|
||||
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<long>();
|
||||
|
||||
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<long>();
|
||||
|
||||
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<long>();
|
||||
|
||||
|
||||
//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<long>();
|
||||
|
||||
//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<long>().Should().Be(FirstInOrderWidgetId);
|
||||
a.ObjectResponse["data"][1]["id"].Value<long>().Should().Be(SecondInOrderWidgetId);
|
||||
a.ObjectResponse["data"][2]["id"].Value<long>().Should().Be(ThirdInOrderWidgetId);
|
||||
a.ObjectResponse["data"][3]["id"].Value<long>().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
|
||||
48
Enum/EnumListOps.cs
Normal file
48
Enum/EnumListOps.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using Xunit;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using FluentAssertions;
|
||||
|
||||
namespace raven_integration
|
||||
{
|
||||
|
||||
public class EnumListOps
|
||||
{
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[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<string>().Should().Be("usertypes");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[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<string>().Should().Be("Client user");
|
||||
a.ObjectResponse["data"][3]["id"].Value<int>().Should().Be(4);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//==================================================
|
||||
|
||||
}//eoc
|
||||
}//eons
|
||||
122
EventLog/EventLog.cs
Normal file
122
EventLog/EventLog.cs
Normal file
@@ -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
|
||||
{
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[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<long>();
|
||||
|
||||
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<DateTime>().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<int>().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<long>();
|
||||
|
||||
//RETRIEVE
|
||||
|
||||
//Get one
|
||||
ApiResponse r3 = await Util.GetAsync("Widget/" + w2Id.ToString(), await Util.GetTokenAsync("InventoryFull"));
|
||||
Util.ValidateDataReturnResponseOk(r3);
|
||||
r3.ObjectResponse["data"]["name"].Value<string>().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<DateTime>().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<int>().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<uint>();
|
||||
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<string>().Should().Be(w.name.ToString());
|
||||
uint concurrencyToken = PUTTestResponse.ObjectResponse["data"]["concurrencyToken"].Value<uint>();
|
||||
|
||||
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<DateTime>().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<int>().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<DateTime>().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<int>().Should().Be(0);//AyEvent 0 = deleted
|
||||
EventLogResponse.ObjectResponse["data"][0]["textra"].Value<string>().Should().Be(w.name.ToString());
|
||||
|
||||
|
||||
}
|
||||
|
||||
//==================================================
|
||||
|
||||
}//eoc
|
||||
}//eons
|
||||
57
ImportV7/ImportV7.cs
Normal file
57
ImportV7/ImportV7.cs
Normal file
@@ -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
|
||||
{
|
||||
//==================================================
|
||||
/// <summary>
|
||||
/// Test Importv7 stuff
|
||||
/// </summary>
|
||||
[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<string>();
|
||||
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
|
||||
59
JobOperations/JobOperations.cs
Normal file
59
JobOperations/JobOperations.cs
Normal file
@@ -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
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[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<String>();
|
||||
|
||||
//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<String>()==jobId)
|
||||
bFound=true;
|
||||
}
|
||||
bFound.Should().BeTrue();
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
//==================================================
|
||||
|
||||
}//eoc
|
||||
}//eons
|
||||
186
Locale/Locale.cs
Normal file
186
Locale/Locale.cs
Normal file
@@ -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<string> keys = new List<string>();
|
||||
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<string>().Should().Be(d.name.ToString());
|
||||
a.ObjectResponse["data"]["stock"].Value<bool>().Should().Be(false);
|
||||
a.ObjectResponse["data"]["id"].Value<long>().Should().BeGreaterThan(4);
|
||||
a.ObjectResponse["data"]["concurrencyToken"].Value<uint>().Should().BeGreaterThan(0);
|
||||
((JArray)a.ObjectResponse["data"]["localeItems"]).Count.Should().BeGreaterThan(0);
|
||||
|
||||
long NewId = a.ObjectResponse["data"]["id"].Value<long>();
|
||||
|
||||
//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<uint>();
|
||||
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<string>().Should().Be(d2.newText.ToString());
|
||||
//uint concurrencyToken = PUTTestResponse.ObjectResponse["data"]["concurrencyToken"].Value<uint>();
|
||||
|
||||
|
||||
//Update locale key
|
||||
var FirstLocaleKey = ((JArray)a.ObjectResponse["data"]["localeItems"])[0];
|
||||
long UpdatedLocaleKeyId = FirstLocaleKey["id"].Value<long>();
|
||||
d2.id = UpdatedLocaleKeyId;
|
||||
d2.newText = Util.Uniquify("INTEGRATION-TEST-LOCALEITEM DISPLAY UPDATE");
|
||||
d2.concurrencyToken = FirstLocaleKey["concurrencyToken"].Value<uint>();
|
||||
|
||||
string UpdatedLocaleKey = FirstLocaleKey["key"].Value<string>();
|
||||
|
||||
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<long>();
|
||||
|
||||
|
||||
|
||||
List<string> keys = new List<string>();
|
||||
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<string>().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
|
||||
67
Locale/RequestedLocaleKeys.cs
Normal file
67
Locale/RequestedLocaleKeys.cs
Normal file
@@ -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<string>();
|
||||
BuildMode.Should().BeOneOf((new string[] { "DEBUG", "RELEASE" }));
|
||||
|
||||
if (BuildMode == "DEBUG")
|
||||
{
|
||||
|
||||
//Make a "list" of keys to fetch the values for
|
||||
List<string> keys = new List<string>();
|
||||
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<int>();
|
||||
RequestedKeyCount.Should().BeGreaterOrEqualTo(2);
|
||||
var NotRequestedKeyCount = a.ObjectResponse["data"]["notRequestedKeyCount"].Value<int>();
|
||||
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
|
||||
32
LogFiles/LogFiles.cs
Normal file
32
LogFiles/LogFiles.cs
Normal file
@@ -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
|
||||
{
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[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
|
||||
51
Metrics/Metrics.cs
Normal file
51
Metrics/Metrics.cs
Normal file
@@ -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
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[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:");
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[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
|
||||
28
Privacy/Privacy.cs
Normal file
28
Privacy/Privacy.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using Xunit;
|
||||
using FluentAssertions;
|
||||
|
||||
namespace raven_integration
|
||||
{
|
||||
|
||||
public class Privacy
|
||||
{
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[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
|
||||
577
Search/SearchOps.cs
Normal file
577
Search/SearchOps.cs
Normal file
@@ -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<long>();
|
||||
|
||||
//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<long>();
|
||||
|
||||
//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<long>();
|
||||
|
||||
//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<long>();
|
||||
|
||||
//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<long>();
|
||||
|
||||
|
||||
//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<long> MatchingIdList = new List<long>();
|
||||
foreach (JObject j in v)
|
||||
{
|
||||
MatchingIdList.Add(j["id"].Value<long>());
|
||||
}
|
||||
|
||||
//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<int>().Should().Be(2);
|
||||
|
||||
//final item must be a user
|
||||
a.ObjectResponse["data"]["searchResults"][MatchingIdList.Count - 1]["type"].Value<int>().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<long>();
|
||||
v = ((JArray)a.ObjectResponse["data"]["searchResults"]);
|
||||
foreach (JObject j in v)
|
||||
{
|
||||
MatchingIdList.Add(j["id"].Value<long>());
|
||||
}
|
||||
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<long>();
|
||||
|
||||
//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<long>();
|
||||
|
||||
|
||||
//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<long> MatchingIdList = new List<long>();
|
||||
foreach (JObject j in v)
|
||||
{
|
||||
MatchingIdList.Add(j["id"].Value<long>());
|
||||
}
|
||||
|
||||
//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<long>();
|
||||
|
||||
//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<long>();
|
||||
|
||||
|
||||
//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<long> MatchingIdList = new List<long>();
|
||||
foreach (JObject j in v)
|
||||
{
|
||||
MatchingIdList.Add(j["id"].Value<long>());
|
||||
}
|
||||
|
||||
//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<long>();
|
||||
|
||||
//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<long>();
|
||||
|
||||
|
||||
//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<long> MatchingIdList = new List<long>();
|
||||
foreach (JObject j in v)
|
||||
{
|
||||
MatchingIdList.Add(j["id"].Value<long>());
|
||||
}
|
||||
|
||||
//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<long>();
|
||||
|
||||
|
||||
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<long>();
|
||||
|
||||
|
||||
|
||||
|
||||
//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<long>();
|
||||
|
||||
|
||||
|
||||
//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<long>();
|
||||
|
||||
|
||||
//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<long> MatchingIdList = new List<long>();
|
||||
foreach (JObject j in v)
|
||||
{
|
||||
MatchingIdList.Add(j["id"].Value<long>());
|
||||
}
|
||||
|
||||
//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<long>();
|
||||
//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<long>();
|
||||
var MatchWidgetSerial = a.ObjectResponse["data"]["serial"].Value<uint>();
|
||||
|
||||
//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<long> MatchingIdList = new List<long>();
|
||||
foreach (JObject j in v)
|
||||
{
|
||||
MatchingIdList.Add(j["id"].Value<long>());
|
||||
}
|
||||
|
||||
//Ensure the expected items are returned
|
||||
MatchingIdList.Should().Contain(MatchWidgetInSerialId, "ShouldContainMatchWidgetInSerialId");
|
||||
|
||||
|
||||
}//eot
|
||||
|
||||
|
||||
//==================================================
|
||||
|
||||
}//eoc
|
||||
}//eons
|
||||
79
ServerState/ServerStateTest.cs
Normal file
79
ServerState/ServerStateTest.cs
Normal file
@@ -0,0 +1,79 @@
|
||||
using Xunit;
|
||||
|
||||
namespace raven_integration
|
||||
{
|
||||
|
||||
public class ServerStateTest
|
||||
{
|
||||
|
||||
|
||||
// ApiFixture fixture;
|
||||
|
||||
// public ServerStateTest(ApiFixture _fixture)
|
||||
// {
|
||||
// this.fixture = _fixture;
|
||||
// }
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Test get state
|
||||
/// </summary>
|
||||
[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
|
||||
|
||||
// /// <summary>
|
||||
// /// Test set state
|
||||
// /// </summary>
|
||||
// [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
|
||||
592
User/UserCrud.cs
Normal file
592
User/UserCrud.cs
Normal file
@@ -0,0 +1,592 @@
|
||||
using System;
|
||||
using Xunit;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using FluentAssertions;
|
||||
|
||||
namespace raven_integration
|
||||
{
|
||||
|
||||
public class UserCrud
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Test all CRUD routes for a User
|
||||
/// </summary>
|
||||
[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<long>();
|
||||
|
||||
|
||||
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<long>();
|
||||
|
||||
|
||||
//RETRIEVE
|
||||
|
||||
//Get one
|
||||
ApiResponse R3 = await Util.GetAsync("User/" + d2Id.ToString(), await Util.GetTokenAsync("manager", "l3tm3in"));
|
||||
Util.ValidateDataReturnResponseOk(R3);
|
||||
R3.ObjectResponse["data"]["name"].Value<string>().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<uint>();
|
||||
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<string>().Should().Be(D2.name.ToString());
|
||||
uint concurrencyToken = PUTTestResponse.ObjectResponse["data"]["concurrencyToken"].Value<uint>();
|
||||
|
||||
//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<string>().Should().Be(newName);
|
||||
|
||||
//DELETE
|
||||
ApiResponse DELETETestResponse = await Util.DeleteAsync("User/" + d2Id.ToString(), await Util.GetTokenAsync("manager", "l3tm3in"));
|
||||
Util.ValidateHTTPStatusCode(DELETETestResponse, 204);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[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<string>().Should().Contain("[E_ACTIVE_NOT_DELETABLE]");
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Test not found
|
||||
/// </summary>
|
||||
[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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test bad modelstate
|
||||
/// </summary>
|
||||
[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");
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[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<long>();
|
||||
uint OriginalConcurrencyToken = R.ObjectResponse["data"]["concurrencyToken"].Value<uint>();
|
||||
|
||||
|
||||
//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);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[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<long>();
|
||||
uint OriginalConcurrencyToken = R.ObjectResponse["data"]["concurrencyToken"].Value<uint>();
|
||||
|
||||
|
||||
//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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[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<long>();
|
||||
uint OriginalConcurrencyToken = R.ObjectResponse["data"]["concurrencyToken"].Value<uint>();
|
||||
|
||||
|
||||
//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);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[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<long>();
|
||||
uint OriginalConcurrencyToken = R.ObjectResponse["data"]["concurrencyToken"].Value<uint>();
|
||||
|
||||
//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);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[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<long>();
|
||||
uint OriginalConcurrencyToken = R.ObjectResponse["data"]["concurrencyToken"].Value<uint>();
|
||||
|
||||
//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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[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<long>();
|
||||
|
||||
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<long>();
|
||||
|
||||
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<long>();
|
||||
|
||||
|
||||
//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<long>();
|
||||
|
||||
//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<long>().Should().Be(FirstInOrdertId);
|
||||
a.ObjectResponse["data"][1]["id"].Value<long>().Should().Be(SecondInOrderId);
|
||||
a.ObjectResponse["data"][2]["id"].Value<long>().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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[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<string>().Replace(" ", "");
|
||||
var secondName = a.ObjectResponse["data"][i + 1]["name"].Value<string>().Replace(" ", "");
|
||||
int comparison = String.Compare(firstName, secondName, comparisonType: StringComparison.OrdinalIgnoreCase);
|
||||
comparison.Should().BeNegative();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[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<long>();
|
||||
|
||||
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<long>();
|
||||
|
||||
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<long>();
|
||||
|
||||
|
||||
//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<long>();
|
||||
|
||||
//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<long>().Should().Be(FirstInOrderId);
|
||||
a.ObjectResponse["data"][1]["id"].Value<long>().Should().Be(SecondInOrderId);
|
||||
a.ObjectResponse["data"][2]["id"].Value<long>().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
|
||||
31
User/UserInactive.cs
Normal file
31
User/UserInactive.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using System;
|
||||
using Xunit;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using FluentAssertions;
|
||||
|
||||
namespace raven_integration
|
||||
{
|
||||
|
||||
public class UserInactive
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Inactive user should not be able to login
|
||||
/// </summary>
|
||||
[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
|
||||
127
User/UserOptionsRu.cs
Normal file
127
User/UserOptionsRu.cs
Normal file
@@ -0,0 +1,127 @@
|
||||
using System;
|
||||
using Xunit;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using FluentAssertions;
|
||||
|
||||
namespace raven_integration
|
||||
{
|
||||
|
||||
public class UserOptionsRu
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Test all CRUD routes for a UserOptions object
|
||||
/// </summary>
|
||||
[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<long>();
|
||||
|
||||
//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<int>().Should().Be(0);
|
||||
uint concurrencyToken = R.ObjectResponse["data"]["concurrencyToken"].Value<uint>();
|
||||
|
||||
//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<string>().Should().Be(D2.emailaddress.ToString());
|
||||
R.ObjectResponse["data"]["timeZoneOffset"].Value<decimal>().Should().Be((decimal)D2.TimeZoneOffset);
|
||||
R.ObjectResponse["data"]["uiColor"].Value<int>().Should().Be((int)D2.UiColor);
|
||||
concurrencyToken = R.ObjectResponse["data"]["concurrencyToken"].Value<uint>();
|
||||
|
||||
|
||||
//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<string>().Should().Be(newEmail);
|
||||
R.ObjectResponse["data"]["timeZoneOffset"].Value<decimal>().Should().Be((decimal)D2.TimeZoneOffset);
|
||||
R.ObjectResponse["data"]["uiColor"].Value<int>().Should().Be((int)D2.UiColor);
|
||||
// concurrencyToken = R.ObjectResponse["data"]["concurrencyToken"].Value<uint>();
|
||||
|
||||
//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);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Test not found
|
||||
/// </summary>
|
||||
[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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test bad modelstate
|
||||
/// </summary>
|
||||
[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
|
||||
244
Widget/WidgetCrud.cs
Normal file
244
Widget/WidgetCrud.cs
Normal file
@@ -0,0 +1,244 @@
|
||||
using System;
|
||||
using Xunit;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using FluentAssertions;
|
||||
|
||||
namespace raven_integration
|
||||
{
|
||||
|
||||
public class WidgetCrud
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Test all CRUD routes for a widget
|
||||
/// </summary>
|
||||
[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<long>();
|
||||
|
||||
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<long>();
|
||||
|
||||
//RETRIEVE
|
||||
|
||||
//Get one
|
||||
ApiResponse r3 = await Util.GetAsync("Widget/" + w2Id.ToString(), await Util.GetTokenAsync("manager", "l3tm3in"));
|
||||
Util.ValidateDataReturnResponseOk(r3);
|
||||
r3.ObjectResponse["data"]["name"].Value<string>().Should().Be(w2.name.ToString());
|
||||
r3.ObjectResponse["data"]["notes"].Value<string>().Should().Be(w2.notes.ToString());
|
||||
var returnedTags = ((JArray)r3.ObjectResponse["data"]["tags"]);
|
||||
returnedTags.Count.Should().Be(7);
|
||||
returnedTags[0].Value<string>().Should().Be("red-tag");
|
||||
returnedTags[1].Value<string>().Should().Be("orange-is-the-new-black");
|
||||
returnedTags[2].Value<string>().Should().Be("yellow");
|
||||
returnedTags[3].Value<string>().Should().Be("green");
|
||||
returnedTags[4].Value<string>().Should().Be("blue");
|
||||
returnedTags[5].Value<string>().Should().Be("indigo");
|
||||
returnedTags[6].Value<string>().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<uint>();
|
||||
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<string>().Should().Be(w2.name.ToString());
|
||||
uint concurrencyToken = PUTTestResponse.ObjectResponse["data"]["concurrencyToken"].Value<uint>();
|
||||
|
||||
//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<string>().Should().Be(newName);
|
||||
|
||||
//DELETE
|
||||
ApiResponse DELETETestResponse = await Util.DeleteAsync("Widget/" + w2Id.ToString(), await Util.GetTokenAsync("manager", "l3tm3in"));
|
||||
Util.ValidateHTTPStatusCode(DELETETestResponse, 204);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Test not found
|
||||
/// </summary>
|
||||
[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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test bad modelstate
|
||||
/// </summary>
|
||||
[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");
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Test server exception
|
||||
/// </summary>
|
||||
[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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Test server alt exception
|
||||
/// </summary>
|
||||
[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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[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<long>();
|
||||
uint OriginalConcurrencyToken = r2.ObjectResponse["data"]["concurrencyToken"].Value<uint>();
|
||||
|
||||
|
||||
|
||||
//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);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[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<long>();
|
||||
uint OriginalConcurrencyToken = r2.ObjectResponse["data"]["concurrencyToken"].Value<uint>();
|
||||
|
||||
|
||||
//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
|
||||
214
Widget/WidgetLists.cs
Normal file
214
Widget/WidgetLists.cs
Normal file
@@ -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
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[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<string>().Replace(" ","");
|
||||
var secondName = a.ObjectResponse["data"][i + 1]["name"].Value<string>().Replace(" ","");
|
||||
int comparison = String.Compare(firstName, secondName, comparisonType: StringComparison.OrdinalIgnoreCase);
|
||||
comparison.Should().BeNegative();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[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<long>();
|
||||
|
||||
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<long>();
|
||||
|
||||
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<long>();
|
||||
|
||||
|
||||
//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<long>();
|
||||
|
||||
//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<long>().Should().Be(FirstInOrderId);
|
||||
a.ObjectResponse["data"][1]["id"].Value<long>().Should().Be(SecondInOrderId);
|
||||
a.ObjectResponse["data"][2]["id"].Value<long>().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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Paging test
|
||||
/// </summary>
|
||||
[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<long>().Should().BeGreaterThan(5);
|
||||
jp["offset"].Value<int>().Should().Be(2);
|
||||
jp["limit"].Value<int>().Should().Be(3);
|
||||
jp["first"].Value<string>().Should().EndWith("&pageSize=3");
|
||||
jp["previous"].Value<string>().Should().EndWith("&pageSize=3");
|
||||
jp["next"].Value<string>().Should().EndWith("&pageSize=3");
|
||||
jp["last"].Value<string>().Should().EndWith("&pageSize=3");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[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<string>().Should().Be("widget");
|
||||
((JArray)a.ObjectResponse["data"]["flds"]).Count.Should().Be(10);
|
||||
|
||||
int DollarAmountFieldNumber = 4;
|
||||
|
||||
a.ObjectResponse["data"]["flds"][DollarAmountFieldNumber]["lt"].Value<string>().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<string>().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<string>().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<string>().Should().Be("Betrag");
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//==================================================
|
||||
|
||||
}//eoc
|
||||
}//eons
|
||||
261
Widget/WidgetRights.cs
Normal file
261
Widget/WidgetRights.cs
Normal file
@@ -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
|
||||
{
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Test not authorized error return
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public async void ServerShouldNotAllowUnauthenticatedAccess()
|
||||
{
|
||||
ApiResponse a = await Util.GetAsync("Widget/list");
|
||||
Util.ValidateHTTPStatusCode(a, 401);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test insufficient read rights error return
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public async void ServerShouldNotAllowReadUnauthorizedAccess()
|
||||
{
|
||||
ApiResponse a = await Util.GetAsync("Widget/listwidgets", await Util.GetTokenAsync( "OpsAdminFull"));
|
||||
//2004 unauthorized
|
||||
Util.ValidateErrorCodeResponse(a, 2004, 401);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Test insufficient create rights error return
|
||||
/// </summary>
|
||||
[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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Test owner rights to modify
|
||||
/// </summary>
|
||||
[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<long>();
|
||||
uint OriginalConcurrencyToken = a.ObjectResponse["data"]["concurrencyToken"].Value<uint>();
|
||||
|
||||
//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);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Test owner rights fails to modify other creator object
|
||||
/// </summary>
|
||||
[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<long>();
|
||||
uint OriginalConcurrencyToken = a.ObjectResponse["data"]["concurrencyToken"].Value<uint>();
|
||||
|
||||
//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);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Test owner rights to modify
|
||||
/// </summary>
|
||||
[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<long>();
|
||||
uint OriginalConcurrencyToken = a.ObjectResponse["data"]["concurrencyToken"].Value<uint>();
|
||||
|
||||
//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);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Test owner rights fails to modify other creator object
|
||||
/// </summary>
|
||||
[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<long>();
|
||||
|
||||
//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);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Test owner rights to delete
|
||||
/// </summary>
|
||||
[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<long>();
|
||||
|
||||
//Now attempt to delete it
|
||||
a = await Util.DeleteAsync("Widget/" + Id.ToString(), await Util.GetTokenAsync( "TechFull"));
|
||||
Util.ValidateHTTPStatusCode(a, 204);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Test owner rights fails to delete other creator object
|
||||
/// </summary>
|
||||
[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<long>();
|
||||
|
||||
//Now attempt delete
|
||||
a = await Util.DeleteAsync("Widget/" + Id.ToString(), await Util.GetTokenAsync( "TechFull"));
|
||||
//2004 unauthorized expected
|
||||
Util.ValidateErrorCodeResponse(a, 2004, 401);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//==================================================
|
||||
|
||||
}//eoc
|
||||
}//eons
|
||||
232
Widget/WidgetValidationTests.cs
Normal file
232
Widget/WidgetValidationTests.cs
Normal file
@@ -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
|
||||
{
|
||||
|
||||
|
||||
// /// <summary>
|
||||
// /// Test business rule should be active on new
|
||||
// /// </summary>
|
||||
// [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");
|
||||
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Test business rule name should be unique
|
||||
/// </summary>
|
||||
[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");
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[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");
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[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");
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[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");
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[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");
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[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");
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[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
|
||||
8
burntest.bat
Normal file
8
burntest.bat
Normal file
@@ -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
|
||||
17
raven-integration.csproj
Normal file
17
raven-integration.csproj
Normal file
@@ -0,0 +1,17 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||
<IsPackable>false</IsPackable>
|
||||
<GenerateFullPaths>true</GenerateFullPaths>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FluentAssertions" Version="5.0.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0" />
|
||||
<PackageReference Include="xunit" Version="2.3.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
|
||||
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
BIN
testdata/ayanova.data.dump.xxx.zip
vendored
Normal file
BIN
testdata/ayanova.data.dump.xxx.zip
vendored
Normal file
Binary file not shown.
BIN
testdata/test.png
vendored
Normal file
BIN
testdata/test.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
BIN
testdata/test.zip
vendored
Normal file
BIN
testdata/test.zip
vendored
Normal file
Binary file not shown.
404
util.cs
Normal file
404
util.cs
Normal file
@@ -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<string, string> authDict = new ConcurrentDictionary<string, string>();//10,32
|
||||
|
||||
private static AutoId Auto { get; } = new AutoId(0);
|
||||
|
||||
public static string Uniquify(string s)
|
||||
{
|
||||
// return s + " " + Auto.GetNext().ToString();
|
||||
return s + " " + (Auto.GetNext() + ((DateTimeOffset)DateTime.Now).ToUnixTimeMilliseconds()).ToString();
|
||||
}
|
||||
|
||||
public async static Task<string> GetTokenAsync(string login, string password = null)
|
||||
{
|
||||
// Console.WriteLine($"GetTokenAsync:{login}");
|
||||
//System.Diagnostics.Trace.WriteLine($"GetTokenAsync:{login}");
|
||||
|
||||
if (password == null)
|
||||
password = login;
|
||||
|
||||
if (!authDict.ContainsKey(login))
|
||||
{
|
||||
dynamic creds = new JObject();
|
||||
creds.login = login;
|
||||
creds.password = password;
|
||||
|
||||
ApiResponse a = await Util.PostAsync("Auth", null, creds.ToString());
|
||||
//Put this in when having concurrency issue during auth and old style dl token creation during login
|
||||
ValidateDataReturnResponseOk(a);
|
||||
|
||||
authDict[login] = a.ObjectResponse["data"]["token"].Value<string>();
|
||||
}
|
||||
return authDict[login];
|
||||
}
|
||||
|
||||
|
||||
|
||||
static bool bInitialized = false;
|
||||
private static void init()
|
||||
{
|
||||
if (bInitialized) return;
|
||||
if (!System.IO.Directory.Exists(TEST_DATA_FOLDER))
|
||||
throw new ArgumentOutOfRangeException($"Test data folder {TEST_DATA_FOLDER} not found, current folder is {System.AppDomain.CurrentDomain.BaseDirectory}");
|
||||
|
||||
client.DefaultRequestHeaders.Accept.Clear();
|
||||
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
|
||||
bInitialized = true;
|
||||
}
|
||||
|
||||
public static string CleanApiRoute(string route)
|
||||
{
|
||||
route = route.TrimStart('/');
|
||||
return API_BASE_URL + route;
|
||||
}
|
||||
|
||||
public async static Task<ApiResponse> GetAsync(string route, string authToken = null, string bodyJsonData = null)
|
||||
{
|
||||
init();
|
||||
|
||||
var requestMessage = new HttpRequestMessage(HttpMethod.Get, CleanApiRoute(route));
|
||||
if (!string.IsNullOrWhiteSpace(authToken))
|
||||
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", authToken);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(bodyJsonData))
|
||||
requestMessage.Content = new StringContent(bodyJsonData, System.Text.Encoding.UTF8, "application/json");
|
||||
|
||||
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
||||
var responseAsString = await response.Content.ReadAsStringAsync();
|
||||
|
||||
return new ApiResponse() { HttpResponse = response, ObjectResponse = Parse(responseAsString) };
|
||||
}
|
||||
|
||||
|
||||
public async static Task<ApiTextResponse> GetTextResultAsync(string route, string authToken = null, string bodyJsonData = null)
|
||||
{
|
||||
init();
|
||||
|
||||
var requestMessage = new HttpRequestMessage(HttpMethod.Get, CleanApiRoute(route));
|
||||
if (!string.IsNullOrWhiteSpace(authToken))
|
||||
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", authToken);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(bodyJsonData))
|
||||
requestMessage.Content = new StringContent(bodyJsonData, System.Text.Encoding.UTF8, "application/json");
|
||||
|
||||
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
||||
var responseAsString = await response.Content.ReadAsStringAsync();
|
||||
|
||||
return new ApiTextResponse() { HttpResponse = response, TextResponse = responseAsString };
|
||||
}
|
||||
|
||||
public static async Task<HttpResponseMessage> DownloadFileAsync(string route, string authToken = null)
|
||||
{
|
||||
|
||||
init();
|
||||
var requestMessage = new HttpRequestMessage(HttpMethod.Get, CleanApiRoute(route));
|
||||
if (!string.IsNullOrWhiteSpace(authToken))
|
||||
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", authToken);
|
||||
|
||||
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
||||
return response;
|
||||
// if (response.IsSuccessStatusCode)
|
||||
// {
|
||||
// return await response.Content.ReadAsByteArrayAsync();
|
||||
// }
|
||||
|
||||
// return null;
|
||||
}
|
||||
|
||||
|
||||
public async static Task<ApiResponse> PostAsync(string route, string authToken = null, string postJson = null)
|
||||
{
|
||||
init();
|
||||
|
||||
var requestMessage = new HttpRequestMessage(HttpMethod.Post, CleanApiRoute(route));
|
||||
if (!string.IsNullOrWhiteSpace(authToken))
|
||||
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", authToken);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(postJson))
|
||||
requestMessage.Content = new StringContent(postJson, System.Text.Encoding.UTF8, "application/json");
|
||||
|
||||
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
||||
var responseAsString = await response.Content.ReadAsStringAsync();
|
||||
|
||||
return new ApiResponse() { HttpResponse = response, ObjectResponse = Parse(responseAsString) };
|
||||
}
|
||||
|
||||
public async static Task<ApiResponse> PostFormDataAsync(string route, MultipartFormDataContent formContent, string authToken = null)
|
||||
{
|
||||
init();
|
||||
|
||||
var requestMessage = new HttpRequestMessage(HttpMethod.Post, CleanApiRoute(route));
|
||||
if (!string.IsNullOrWhiteSpace(authToken))
|
||||
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", authToken);
|
||||
|
||||
requestMessage.Content = formContent;
|
||||
|
||||
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
||||
var responseAsString = await response.Content.ReadAsStringAsync();
|
||||
|
||||
return new ApiResponse() { HttpResponse = response, ObjectResponse = Parse(responseAsString) };
|
||||
}
|
||||
|
||||
|
||||
public async static Task<ApiResponse> PutAsync(string route, string authToken = null, string putJson = null)
|
||||
{
|
||||
init();
|
||||
|
||||
var requestMessage = new HttpRequestMessage(HttpMethod.Put, CleanApiRoute(route));
|
||||
if (!string.IsNullOrWhiteSpace(authToken))
|
||||
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", authToken);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(putJson))
|
||||
requestMessage.Content = new StringContent(putJson, System.Text.Encoding.UTF8, "application/json");
|
||||
|
||||
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
||||
var responseAsString = await response.Content.ReadAsStringAsync();
|
||||
|
||||
return new ApiResponse() { HttpResponse = response, ObjectResponse = Parse(responseAsString) };
|
||||
}
|
||||
|
||||
|
||||
public async static Task<ApiResponse> PatchAsync(string route, string authToken = null, string patchJson = null)
|
||||
{
|
||||
init();
|
||||
|
||||
var method = new HttpMethod("PATCH");
|
||||
|
||||
var requestMessage = new HttpRequestMessage(method, CleanApiRoute(route));
|
||||
if (!string.IsNullOrWhiteSpace(authToken))
|
||||
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", authToken);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(patchJson))
|
||||
requestMessage.Content = new StringContent(patchJson, System.Text.Encoding.UTF8, "application/json-patch+json");
|
||||
|
||||
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
||||
var responseAsString = await response.Content.ReadAsStringAsync();
|
||||
|
||||
return new ApiResponse() { HttpResponse = response, ObjectResponse = Parse(responseAsString) };
|
||||
}
|
||||
|
||||
|
||||
public async static Task<ApiResponse> DeleteAsync(string route, string authToken = null)
|
||||
{
|
||||
init();
|
||||
|
||||
var requestMessage = new HttpRequestMessage(HttpMethod.Delete, CleanApiRoute(route));
|
||||
if (!string.IsNullOrWhiteSpace(authToken))
|
||||
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", authToken);
|
||||
|
||||
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
||||
var responseAsString = await response.Content.ReadAsStringAsync();
|
||||
|
||||
return new ApiResponse() { HttpResponse = response, ObjectResponse = Parse(responseAsString) };
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="jsonString"></param>
|
||||
/// <returns></returns>
|
||||
private static JObject Parse(string jsonString)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(jsonString))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return JObject.Parse(jsonString);
|
||||
}
|
||||
|
||||
//https://www.newtonsoft.com/json/help/html/FromObject.htm
|
||||
private static string ObjectToJsonString(object o)
|
||||
{
|
||||
JObject j = (JObject)JToken.FromObject(o);
|
||||
return j.ToString();
|
||||
}
|
||||
|
||||
public static void ValidateDataReturnResponseOk(ApiResponse a)
|
||||
{
|
||||
var ErrorMessage = string.Empty;
|
||||
var ERR = a.ObjectResponse["error"];
|
||||
if (ERR != null)
|
||||
{
|
||||
var ecode = ERR["code"];
|
||||
if (ecode != null)
|
||||
ErrorMessage += $"CODE: {ecode} ";
|
||||
|
||||
var emsg = ERR["message"];
|
||||
if (emsg != null)
|
||||
ErrorMessage += $"MESSAGE: {emsg} ";
|
||||
|
||||
var etarget = ERR["target"];
|
||||
if (etarget != null)
|
||||
ErrorMessage += $"TARGET: {etarget} ";
|
||||
}
|
||||
|
||||
a.ObjectResponse["error"].Should().BeNull("because there should not be an error on an api call, error was: {0}", ErrorMessage);
|
||||
a.ObjectResponse["data"].Should().NotBeNull("A result should be returned");
|
||||
}
|
||||
|
||||
public static void ValidateNoErrorInResponse(ApiResponse a)
|
||||
{
|
||||
a.ObjectResponse["error"].Should().BeNull("There should not be an error on an api call");
|
||||
}
|
||||
|
||||
public static void ValidateHTTPStatusCode(ApiResponse a, int DesiredStatusCode)
|
||||
{
|
||||
((int)a.HttpResponse.StatusCode).Should().Be(DesiredStatusCode);
|
||||
}
|
||||
|
||||
public static void ValidateHTTPStatusCode(ApiTextResponse t, int DesiredStatusCode)
|
||||
{
|
||||
((int)t.HttpResponse.StatusCode).Should().Be(DesiredStatusCode);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// validate a not found response
|
||||
/// </summary>
|
||||
/// <param name="a"></param>
|
||||
public static void ValidateResponseNotFound(ApiResponse a)
|
||||
{
|
||||
((int)a.HttpResponse.StatusCode).Should().Be(404);
|
||||
a.ObjectResponse["error"].Should().NotBeNull("There should be an error on the api call");
|
||||
a.ObjectResponse["error"]["code"].Value<int>().Should().Be(2010);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// validate a concurrency error
|
||||
/// </summary>
|
||||
/// <param name="a"></param>
|
||||
public static void ValidateConcurrencyError(ApiResponse a)
|
||||
{
|
||||
((int)a.HttpResponse.StatusCode).Should().Be(409);
|
||||
a.ObjectResponse["error"].Should().NotBeNull("There should be an error on the api call");
|
||||
a.ObjectResponse["error"]["code"].Value<int>().Should().Be(2005);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// validate that the call violates referential integrity
|
||||
/// </summary>
|
||||
/// <param name="a"></param>
|
||||
public static void ValidateViolatesReferentialIntegrityError(ApiResponse a)
|
||||
{
|
||||
((int)a.HttpResponse.StatusCode).Should().Be(400);
|
||||
a.ObjectResponse["error"].Should().NotBeNull("There should be an error on the api call");
|
||||
a.ObjectResponse["error"]["code"].Value<int>().Should().Be(2200);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// validate a bad ModelState response
|
||||
/// </summary>
|
||||
/// <param name="a"></param>
|
||||
public static void ValidateBadModelStateResponse(ApiResponse a, string CheckFirstTargetExists = null)
|
||||
{
|
||||
((int)a.HttpResponse.StatusCode).Should().Be(400);
|
||||
a.ObjectResponse["error"].Should().NotBeNull("There should be an error on the api call");
|
||||
a.ObjectResponse["error"]["code"].Value<int>().Should().Be(2200);
|
||||
a.ObjectResponse["error"]["details"].Should().NotBeNull("There should be error details on the api call");
|
||||
if (!string.IsNullOrWhiteSpace(CheckFirstTargetExists))
|
||||
{
|
||||
a.ObjectResponse["error"]["details"][0]["target"].Value<string>().Should().Be(CheckFirstTargetExists);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// public enum ValidationErrorType
|
||||
// {
|
||||
// RequiredPropertyEmpty = 1,
|
||||
// LengthExceeded = 2,
|
||||
// NotUnique = 3,
|
||||
// StartDateMustComeBeforeEndDate = 4,
|
||||
// InvalidValue = 5
|
||||
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// assert contains validation target and error code
|
||||
/// </summary>
|
||||
/// <param name="a"></param>
|
||||
/// <param name="target"></param>
|
||||
/// <param name="error"></param>
|
||||
public static void ShouldContainValidationError(ApiResponse a, string target, string error, string message = null)
|
||||
{
|
||||
a.ObjectResponse["error"]["details"].Should().NotBeNull("There should be Details on the api call");
|
||||
if (message != null)
|
||||
{
|
||||
a.ObjectResponse["error"]["details"].Should().Contain(
|
||||
m => m["target"].Value<string>() == target &&
|
||||
m["error"].Value<string>() == error &&
|
||||
m["message"].Value<string>() == message);
|
||||
}
|
||||
else
|
||||
{
|
||||
a.ObjectResponse["error"]["details"].Should().Contain(m => m["target"].Value<string>() == target && m["error"].Value<string>() == error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// validate server exception response
|
||||
/// </summary>
|
||||
/// <param name="a"></param>
|
||||
public static void ValidateServerExceptionResponse(ApiResponse a)
|
||||
{
|
||||
((int)a.HttpResponse.StatusCode).Should().Be(500);
|
||||
a.ObjectResponse["error"].Should().NotBeNull("There should be an error on the api call");
|
||||
a.ObjectResponse["error"]["code"].Value<int>().Should().Be(2002);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Validate an expected api error code and http code response
|
||||
/// </summary>
|
||||
/// <param name="a"></param>
|
||||
/// <param name="apiErrorCode"></param>
|
||||
/// <param name="httpStatusCode"></param>
|
||||
public static void ValidateErrorCodeResponse(ApiResponse a, int apiErrorCode, int httpStatusCode)
|
||||
{
|
||||
((int)a.HttpResponse.StatusCode).Should().Be(httpStatusCode);
|
||||
a.ObjectResponse["error"].Should().NotBeNull("There should be an error on the api call");
|
||||
a.ObjectResponse["error"]["code"].Value<int>().Should().Be(apiErrorCode);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}//eoc
|
||||
}//eons
|
||||
Reference in New Issue
Block a user