From 6fbf7f1b84ec6b7afa627b65c7447754957886ad Mon Sep 17 00:00:00 2001 From: Dav Evans Date: Tue, 29 Jul 2014 20:00:38 +1000 Subject: [PATCH] Add Model validation and unit test for HTTP 400s --- .../Church.Host.Owin.Core.csproj | 1 + .../Controllers/ChurchController.cs | 5 +- src/Church/Church.Host.Owin.Core/Startup.cs | 3 + .../ViewModels/ChurchViewModel.cs | 10 ++- .../ViewModels/TimeZoneViewModel.cs | 12 +++ .../ChurchControllerTests.cs | 80 +++++++++++++++++-- 6 files changed, 102 insertions(+), 9 deletions(-) create mode 100644 src/Church/Church.Host.Owin.Core/ViewModels/TimeZoneViewModel.cs diff --git a/src/Church/Church.Host.Owin.Core/Church.Host.Owin.Core.csproj b/src/Church/Church.Host.Owin.Core/Church.Host.Owin.Core.csproj index 23759a1..8e7dd0d 100644 --- a/src/Church/Church.Host.Owin.Core/Church.Host.Owin.Core.csproj +++ b/src/Church/Church.Host.Owin.Core/Church.Host.Owin.Core.csproj @@ -109,6 +109,7 @@ + diff --git a/src/Church/Church.Host.Owin.Core/Controllers/ChurchController.cs b/src/Church/Church.Host.Owin.Core/Controllers/ChurchController.cs index 759d29c..efa8d71 100644 --- a/src/Church/Church.Host.Owin.Core/Controllers/ChurchController.cs +++ b/src/Church/Church.Host.Owin.Core/Controllers/ChurchController.cs @@ -31,7 +31,10 @@ public HttpResponseMessage ChurchById(int churchId) [Route("api/church")] public HttpResponseMessage AddChurch([FromBody]ChurchViewModel churchViewModel) { - //todo: validate churchViewModel + if (!ModelState.IsValid) + { + return Request.CreateErrorResponse(HttpStatusCode.BadRequest, @"Invalid Church"); + } var church = Mapper.Map(churchViewModel); _churchService.Add(church); diff --git a/src/Church/Church.Host.Owin.Core/Startup.cs b/src/Church/Church.Host.Owin.Core/Startup.cs index e7badfe..7bfe528 100644 --- a/src/Church/Church.Host.Owin.Core/Startup.cs +++ b/src/Church/Church.Host.Owin.Core/Startup.cs @@ -36,6 +36,9 @@ void RegisterComponents(TinyIoCContainer container) private void RegisterMappings() { + Mapper.CreateMap(); + Mapper.CreateMap(); + Mapper.CreateMap() .ForMember(x => x.Id, o => o.MapFrom(d => d.Id)) .ForMember(x => x.Name, o => o.MapFrom(d => d.Name)) diff --git a/src/Church/Church.Host.Owin.Core/ViewModels/ChurchViewModel.cs b/src/Church/Church.Host.Owin.Core/ViewModels/ChurchViewModel.cs index 952badd..7695676 100644 --- a/src/Church/Church.Host.Owin.Core/ViewModels/ChurchViewModel.cs +++ b/src/Church/Church.Host.Owin.Core/ViewModels/ChurchViewModel.cs @@ -1,9 +1,15 @@ -namespace Church.Host.Owin.Core.ViewModels +using System.ComponentModel.DataAnnotations; + +namespace Church.Host.Owin.Core.ViewModels { public class ChurchViewModel { public int Id { get; set; } + + [Required(AllowEmptyStrings = false, ErrorMessage = "Name is required.")] public string Name { get; set; } - public Model.Core.TimeZone TimeZone { get; set; } + + [Required(ErrorMessage = "TimeZone is requried.")] + public TimeZoneViewModel TimeZone { get; set; } } } diff --git a/src/Church/Church.Host.Owin.Core/ViewModels/TimeZoneViewModel.cs b/src/Church/Church.Host.Owin.Core/ViewModels/TimeZoneViewModel.cs new file mode 100644 index 0000000..63b678e --- /dev/null +++ b/src/Church/Church.Host.Owin.Core/ViewModels/TimeZoneViewModel.cs @@ -0,0 +1,12 @@ +using System.ComponentModel.DataAnnotations; + +namespace Church.Host.Owin.Core.ViewModels +{ + public class TimeZoneViewModel + { + [Required] + public int Id { get; set; } + [Required] + public string Name { get; set; } + } +} \ No newline at end of file diff --git a/src/Church/Church.IntegrationTests/ChurchControllerTests.cs b/src/Church/Church.IntegrationTests/ChurchControllerTests.cs index dc5036e..84c671c 100644 --- a/src/Church/Church.IntegrationTests/ChurchControllerTests.cs +++ b/src/Church/Church.IntegrationTests/ChurchControllerTests.cs @@ -93,7 +93,32 @@ public void ReturnsCreatedHttpStatusCode() var churchViewModel = new ChurchViewModel { Name = "Foo", - TimeZone = new TimeZone + TimeZone = new TimeZoneViewModel + { + Id = 20, + Name = "Sydney" + } + }; + + var mockChurchService = MockRepository.GenerateStub(); + mockChurchService.Stub(x => x.Add(Arg.Is.Anything)); + Container.Register(typeof (IChurchService), mockChurchService); + + //ACT + var response = Server.HttpClient.PostAsJsonAsync("/api/church", churchViewModel).Result; + + //ASSERT + Assert.AreEqual(HttpStatusCode.Created, response.StatusCode, "Expected HttpStatusCode of CREATED"); + } + + [Test] + public void ReturnsChurchWithId() + { + //arrange + var churchViewModel = new ChurchViewModel + { + Name = "Foo", + TimeZone = new TimeZoneViewModel { Id = 20, Name = "Sydney" @@ -104,19 +129,62 @@ public void ReturnsCreatedHttpStatusCode() mockChurchService.Stub(x => x.Add(Arg.Is.Anything)) .Callback((Model.Core.Church c) => { - c.Id = 101; - return true; + c.Id = 101; + return true; }); - - Container.Register(typeof (IChurchService), mockChurchService); + + Container.Register(typeof(IChurchService), mockChurchService); //ACT var response = Server.HttpClient.PostAsJsonAsync("/api/church", churchViewModel).Result; + var newChurch = JsonConvert.DeserializeObject(response.Content.ReadAsStringAsync().Result); //ASSERT - Assert.AreEqual(HttpStatusCode.Created, response.StatusCode, "Expected HttpStatusCode of CREATED"); + Assert.AreEqual(101, newChurch.Id, "expected id 101"); + } + [Test] + public void ReturnsBadRequestForChurchWithNoName() + { + //arrange + var churchViewModel = new ChurchViewModel + { + Name = null, + TimeZone = new TimeZoneViewModel + { + Id = 20, + Name = "Sydney" + } + }; + + var mockChurchService = MockRepository.GenerateStub(); + Container.Register(typeof(IChurchService), mockChurchService); + + //ACT + var response = Server.HttpClient.PostAsJsonAsync("/api/church", churchViewModel).Result; + + //ASSERT + Assert.AreEqual(HttpStatusCode.BadRequest, response.StatusCode, "Expected HttpStatusCode of BadRequest"); + } + + [Test] + public void ReturnsBadRequestForChurchWithNoTimeZone() + { + //arrange + var churchViewModel = new ChurchViewModel + { + Name = "MyChurch", + }; + + var mockChurchService = MockRepository.GenerateStub(); + Container.Register(typeof(IChurchService), mockChurchService); + + //ACT + var response = Server.HttpClient.PostAsJsonAsync("/api/church", churchViewModel).Result; + + //ASSERT + Assert.AreEqual(HttpStatusCode.BadRequest, response.StatusCode, "Expected HttpStatusCode of BadRequest"); } }