This commit is contained in:
2018-09-04 18:58:10 +00:00
parent 077b9c7617
commit 21eb952e5a
5 changed files with 230 additions and 9 deletions

View File

@@ -30,8 +30,7 @@ IMMEDIATE ITEMS:
================
- USER OBJECT
- User route and controller and biz object
- User routes for create update delete the core User object (no user settings in it) {also see rights in BizRoles.cs as it is not fully fleshed out yet}
- Tests for user routes
- USER OPTIONS OBJECT
- UserOptions object and routes will be used for user configurable settings, some of it initial shell (timezone, email etc), not core User stuff to avoid any rights issues or confusion or bypasses

View File

@@ -98,8 +98,8 @@ namespace AyaNova.Api.Controllers
///
/// </summary>
/// <returns>Paged collection of Users with paging data</returns>
[HttpGet("List", Name = nameof(List))]//We MUST have a "Name" defined or we can't get the link for the pagination, non paged urls don't need a name
public async Task<IActionResult> List([FromQuery] PagingOptions pagingOptions)
[HttpGet("ListUsers", Name = nameof(ListUsers))]//We MUST have a "Name" defined or we can't get the link for the pagination, non paged urls don't need a name
public async Task<IActionResult> ListUsers([FromQuery] PagingOptions pagingOptions)
{
if (serverState.IsClosed)
@@ -120,7 +120,7 @@ namespace AyaNova.Api.Controllers
//Instantiate the business object handler
UserBiz biz = new UserBiz(ct, UserIdFromContext.Id(HttpContext.Items), UserRolesFromContext.Roles(HttpContext.Items));
ApiPagedResponse<User> pr = await biz.GetManyAsync(Url, nameof(List), pagingOptions);
ApiPagedResponse<User> pr = await biz.GetManyAsync(Url, nameof(ListUsers), pagingOptions);
return Ok(new ApiOkWithPagingResponse<User>(pr));
}

View File

@@ -100,8 +100,8 @@ namespace AyaNova.Api.Controllers
///
/// </summary>
/// <returns>Paged collection of widgets with paging data</returns>
[HttpGet("List", Name = nameof(List))]//We MUST have a "Name" defined or we can't get the link for the pagination, non paged urls don't need a name
public async Task<IActionResult> List([FromQuery] PagingOptions pagingOptions)
[HttpGet("ListWidgets", Name = nameof(ListWidgets))]//We MUST have a "Name" defined or we can't get the link for the pagination, non paged urls don't need a name
public async Task<IActionResult> ListWidgets([FromQuery] PagingOptions pagingOptions)
{
if (serverState.IsClosed)
{
@@ -121,7 +121,7 @@ namespace AyaNova.Api.Controllers
//Instantiate the business object handler
WidgetBiz biz = new WidgetBiz(ct, UserIdFromContext.Id(HttpContext.Items), UserRolesFromContext.Roles(HttpContext.Items));
ApiPagedResponse<Widget> pr = await biz.GetManyAsync(Url, nameof(List), pagingOptions);
ApiPagedResponse<Widget> pr = await biz.GetManyAsync(Url, nameof(ListWidgets), pagingOptions);
return Ok(new ApiOkWithPagingResponse<Widget>(pr));
}

View File

@@ -0,0 +1,222 @@
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()
{
/*
{
"id": 0,
"name": "string",
"dollarAmount": 0,
"active": true,
"roles": 0
}
*/
//CREATE
dynamic w1 = new JObject();
w1.name = Util.Uniquify("First Test User");
w1.dollarAmount = 1.11m;
w1.active = true;
w1.roles = 0;
ApiResponse r1 = await Util.PostAsync("User", await Util.GetTokenAsync("manager", "l3tm3in"), w1.ToString());
Util.ValidateDataReturnResponseOk(r1);
long w1Id = r1.ObjectResponse["result"]["id"].Value<long>();
dynamic w2 = new JObject();
w2.name = Util.Uniquify("Second Test User");
w2.dollarAmount = 2.22m;
w2.active = true;
w2.roles = 0;
ApiResponse r2 = await Util.PostAsync("User", await Util.GetTokenAsync( "manager", "l3tm3in"), w2.ToString());
Util.ValidateDataReturnResponseOk(r2);
long w2Id = r2.ObjectResponse["result"]["id"].Value<long>();
//RETRIEVE
//Get one
ApiResponse r3 = await Util.GetAsync("User/" + w2Id.ToString(), await Util.GetTokenAsync( "manager", "l3tm3in"));
Util.ValidateDataReturnResponseOk(r3);
r3.ObjectResponse["result"]["name"].Value<string>().Should().Be(w2.name.ToString());
//UPDATE
//PUT
//update w2id
w2.name = Util.Uniquify("UPDATED VIA PUT SECOND TEST User");
w2.OwnerId = 1;
w2.concurrencyToken = r2.ObjectResponse["result"]["concurrencyToken"].Value<uint>();
ApiResponse PUTTestResponse = await Util.PutAsync("User/" + w2Id.ToString(), await Util.GetTokenAsync( "manager", "l3tm3in"), w2.ToString());
Util.ValidateHTTPStatusCode(PUTTestResponse, 200);
//check PUT worked
ApiResponse checkPUTWorked = await Util.GetAsync("User/" + w2Id.ToString(), await Util.GetTokenAsync( "manager", "l3tm3in"));
Util.ValidateNoErrorInResponse(checkPUTWorked);
checkPUTWorked.ObjectResponse["result"]["name"].Value<string>().Should().Be(w2.name.ToString());
uint concurrencyToken = PUTTestResponse.ObjectResponse["result"]["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/" + w2Id.ToString() + "/" + concurrencyToken.ToString(), await Util.GetTokenAsync( "manager", "l3tm3in"), patchJson);
Util.ValidateHTTPStatusCode(PATCHTestResponse, 200);
//check PATCH worked
ApiResponse checkPATCHWorked = await Util.GetAsync("User/" + w2Id.ToString(), await Util.GetTokenAsync( "manager", "l3tm3in"));
Util.ValidateNoErrorInResponse(checkPATCHWorked);
checkPATCHWorked.ObjectResponse["result"]["name"].Value<string>().Should().Be(newName);
//DELETE
ApiResponse DELETETestResponse = await Util.DeleteAsync("User/" + 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("User/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("User/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("User/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("User/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("User", await Util.GetTokenAsync( "manager", "l3tm3in"), w2.ToString());
Util.ValidateDataReturnResponseOk(r2);
long w2Id = r2.ObjectResponse["result"]["id"].Value<long>();
uint OriginalConcurrencyToken = r2.ObjectResponse["result"]["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("User/" + 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("User", await Util.GetTokenAsync( "manager", "l3tm3in"), w2.ToString());
Util.ValidateDataReturnResponseOk(r2);
long w2Id = r2.ObjectResponse["result"]["id"].Value<long>();
uint OriginalConcurrencyToken = r2.ObjectResponse["result"]["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);
}
//==================================================
}//eoc
}//eons

View File

@@ -44,7 +44,7 @@ namespace raven_integration
public async void PagingShouldWorkAsExpected()
{
//Get all
ApiResponse a = await Util.GetAsync("Widget/list?Offset=2&Limit=3", await Util.GetTokenAsync( "manager", "l3tm3in"));
ApiResponse a = await Util.GetAsync("Widget/listwidgets?Offset=2&Limit=3", await Util.GetTokenAsync( "manager", "l3tm3in"));
Util.ValidateDataReturnResponseOk(a);
Util.ValidateHTTPStatusCode(a, 200);