From 21eb952e5ae2fb6442e1f8c109758bd3c37f080b Mon Sep 17 00:00:00 2001 From: John Cardinal Date: Tue, 4 Sep 2018 18:58:10 +0000 Subject: [PATCH] --- devdocs/todo.txt | 3 +- server/AyaNova/Controllers/UserController.cs | 6 +- .../AyaNova/Controllers/WidgetController.cs | 6 +- test/raven-integration/User/UserCrud.cs | 222 ++++++++++++++++++ test/raven-integration/Widget/WidgetLists.cs | 2 +- 5 files changed, 230 insertions(+), 9 deletions(-) create mode 100644 test/raven-integration/User/UserCrud.cs diff --git a/devdocs/todo.txt b/devdocs/todo.txt index 4e62a07d..609920a0 100644 --- a/devdocs/todo.txt +++ b/devdocs/todo.txt @@ -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 diff --git a/server/AyaNova/Controllers/UserController.cs b/server/AyaNova/Controllers/UserController.cs index 6f3efa39..69a04e83 100644 --- a/server/AyaNova/Controllers/UserController.cs +++ b/server/AyaNova/Controllers/UserController.cs @@ -98,8 +98,8 @@ namespace AyaNova.Api.Controllers /// /// /// Paged collection of Users with paging data - [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 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 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 pr = await biz.GetManyAsync(Url, nameof(List), pagingOptions); + ApiPagedResponse pr = await biz.GetManyAsync(Url, nameof(ListUsers), pagingOptions); return Ok(new ApiOkWithPagingResponse(pr)); } diff --git a/server/AyaNova/Controllers/WidgetController.cs b/server/AyaNova/Controllers/WidgetController.cs index b92a5bee..1976a2f7 100644 --- a/server/AyaNova/Controllers/WidgetController.cs +++ b/server/AyaNova/Controllers/WidgetController.cs @@ -100,8 +100,8 @@ namespace AyaNova.Api.Controllers /// /// /// Paged collection of widgets with paging data - [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 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 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 pr = await biz.GetManyAsync(Url, nameof(List), pagingOptions); + ApiPagedResponse pr = await biz.GetManyAsync(Url, nameof(ListWidgets), pagingOptions); return Ok(new ApiOkWithPagingResponse(pr)); } diff --git a/test/raven-integration/User/UserCrud.cs b/test/raven-integration/User/UserCrud.cs new file mode 100644 index 00000000..7e494a5f --- /dev/null +++ b/test/raven-integration/User/UserCrud.cs @@ -0,0 +1,222 @@ +using System; +using Xunit; +using Newtonsoft.Json.Linq; +using FluentAssertions; + +namespace raven_integration +{ + + public class UserCrud + { + + /// + /// Test all CRUD routes for a User + /// + [Fact] + public async void CRUD() + { + /* + { + "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(); + + + 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(); + + + //RETRIEVE + + //Get one + ApiResponse r3 = await Util.GetAsync("User/" + w2Id.ToString(), await Util.GetTokenAsync( "manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(r3); + r3.ObjectResponse["result"]["name"].Value().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(); + 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().Should().Be(w2.name.ToString()); + uint concurrencyToken = PUTTestResponse.ObjectResponse["result"]["concurrencyToken"].Value(); + + //PATCH + var newName = Util.Uniquify("UPDATED VIA PATCH SECOND TEST User"); + string patchJson = "[{\"value\": \"" + newName + "\",\"path\": \"/name\",\"op\": \"replace\"}]"; + ApiResponse PATCHTestResponse = await Util.PatchAsync("User/" + 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().Should().Be(newName); + + //DELETE + ApiResponse DELETETestResponse = await Util.DeleteAsync("User/" + w2Id.ToString(), await Util.GetTokenAsync( "manager", "l3tm3in")); + Util.ValidateHTTPStatusCode(DELETETestResponse, 204); + } + + + + + + + /// + /// Test not found + /// + [Fact] + public async void GetNonExistentItemShouldError() + { + //Get non existant + //Should return status code 404, api error code 2010 + ApiResponse a = await Util.GetAsync("User/999999", await Util.GetTokenAsync( "manager", "l3tm3in")); + Util.ValidateResponseNotFound(a); + } + + /// + /// Test bad modelstate + /// + [Fact] + public async void GetBadModelStateShouldError() + { + //Get non existant + //Should return status code 400, api error code 2200 and a first target in details of "id" + ApiResponse a = await Util.GetAsync("User/2q2", await Util.GetTokenAsync( "manager", "l3tm3in")); + Util.ValidateBadModelStateResponse(a, "id"); + } + + + /// + /// Test server exception + /// + [Fact] + public async void ServerExceptionShouldErrorPropertly() + { + //Get non existant + //Should return status code 400, api error code 2200 and a first target in details of "id" + ApiResponse a = await Util.GetAsync("User/exception", await Util.GetTokenAsync( "manager", "l3tm3in")); + Util.ValidateServerExceptionResponse(a); + } + + + + /// + /// Test server alt exception + /// + [Fact] + public async void ServerAltExceptionShouldErrorPropertly() + { + //Get non existant + //Should return status code 400, api error code 2200 and a first target in details of "id" + ApiResponse a = await Util.GetAsync("User/altexception", await Util.GetTokenAsync( "manager", "l3tm3in")); + Util.ValidateServerExceptionResponse(a); + } + + + + + /// + /// + /// + [Fact] + public async void PutConcurrencyViolationShouldFail() + { + + //CREATE + + dynamic w2 = new JObject(); + w2.name = Util.Uniquify("PutConcurrencyViolationShouldFail"); + w2.dollarAmount = 2.22m; + w2.active = true; + w2.roles = 0; + + ApiResponse r2 = await Util.PostAsync("User", await Util.GetTokenAsync( "manager", "l3tm3in"), w2.ToString()); + Util.ValidateDataReturnResponseOk(r2); + long w2Id = r2.ObjectResponse["result"]["id"].Value(); + uint OriginalConcurrencyToken = r2.ObjectResponse["result"]["concurrencyToken"].Value(); + + + + //UPDATE + //PUT + + w2.name = Util.Uniquify("PutConcurrencyViolationShouldFail UPDATE VIA PUT "); + w2.OwnerId = 1; + w2.concurrencyToken = OriginalConcurrencyToken - 1;//bad token + ApiResponse PUTTestResponse = await Util.PutAsync("User/" + w2Id.ToString(), await Util.GetTokenAsync( "manager", "l3tm3in"), w2.ToString()); + Util.ValidateConcurrencyError(PUTTestResponse); + + + } + + + + + /// + /// + /// + [Fact] + public async void PatchConcurrencyViolationShouldFail() + { + + //CREATE + + dynamic w2 = new JObject(); + w2.name = Util.Uniquify("PatchConcurrencyViolationShouldFail"); + w2.dollarAmount = 2.22m; + w2.active = true; + w2.roles = 0; + + ApiResponse r2 = await Util.PostAsync("User", await Util.GetTokenAsync( "manager", "l3tm3in"), w2.ToString()); + Util.ValidateDataReturnResponseOk(r2); + long w2Id = r2.ObjectResponse["result"]["id"].Value(); + uint OriginalConcurrencyToken = r2.ObjectResponse["result"]["concurrencyToken"].Value(); + + + //PATCH + var newName = Util.Uniquify("PutConcurrencyViolationShouldFail UPDATED VIA PATCH"); + string patchJson = "[{\"value\": \"" + newName + "\",\"path\": \"/name\",\"op\": \"replace\"}]"; + ApiResponse PATCHTestResponse = await Util.PatchAsync("User/" + w2Id.ToString() + "/" + (OriginalConcurrencyToken - 1).ToString(), await Util.GetTokenAsync( "manager", "l3tm3in"), patchJson); + Util.ValidateConcurrencyError(PATCHTestResponse); + } + + + + + + //================================================== + + }//eoc +}//eons diff --git a/test/raven-integration/Widget/WidgetLists.cs b/test/raven-integration/Widget/WidgetLists.cs index 4dba465d..49fa6f3b 100644 --- a/test/raven-integration/Widget/WidgetLists.cs +++ b/test/raven-integration/Widget/WidgetLists.cs @@ -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);