diff --git a/src/Robware.Api.Blog.Tests/BlogControllerTests.cs b/src/Robware.Api.Blog.Tests/BlogControllerTests.cs index 9912878..2027957 100644 --- a/src/Robware.Api.Blog.Tests/BlogControllerTests.cs +++ b/src/Robware.Api.Blog.Tests/BlogControllerTests.cs @@ -5,12 +5,18 @@ using Microsoft.Extensions.Logging; using NSubstitute; using NSubstitute.ExceptionExtensions; using Robware.Api.Blog.Controllers; +using Robware.Api.Blog.Models; using Robware.Blog; using Robware.Data; using Xunit; namespace Robware.Api.Blog.Tests { public class BlogControllerTests { + private bool ShouldBeEquivalentTo(T post, T expected) { + post.Should().BeEquivalentTo(expected); + return true; + } + [Fact] public async Task Get_WithUrl_ReturnsBlogPost() { var logger = Substitute.For>(); @@ -154,5 +160,68 @@ namespace Robware.Api.Blog.Tests { var controller = new BlogController(logger, repo); (await controller.GetCount()).Value.Should().Be(0); } + + [Fact] + public async Task Save_WithNewSubmission_Returns200() { + var logger = Substitute.For>(); + var repo = Substitute.For(); + + var submission = new BlogPostSubmission { + Content = "content", + Title = "title" + }; + + var controller = new BlogController(logger, repo); + (await controller.SavePost(submission)).Should().BeOfType(); + + var expected = new BlogPost { + Title = "title", + Draft = "content", + Url = "title" + }; + + await repo.Received(1).SavePost(Arg.Is(post => ShouldBeEquivalentTo(post, expected))); + } + + [Fact] + public async Task Save_WithExistingSubmission_Returns200() { + var logger = Substitute.For>(); + var repo = Substitute.For(); + repo.GetPostByIdAsync(1).Returns(new BlogPost {Content = "old content"}); + + var submission = new BlogPostSubmission { + Id = 1, + Content = "new content", + Title = "title" + }; + + var controller = new BlogController(logger, repo); + (await controller.SavePost(submission)).Should().BeOfType(); + + var expected = new BlogPost { + Title = "title", + Content = "old content", + Draft = "new content", + Url = "title" + }; + + await repo.Received(1).SavePost(Arg.Is(post => ShouldBeEquivalentTo(post, expected))); + } + + [Fact] + public async Task Save_WithExistingSubmission_WherePostDoesntExist_Returns400() { + var logger = Substitute.For>(); + var repo = Substitute.For(); + repo.GetPostByIdAsync(1).Throws(new ItemNotFoundException("", null)); + + var submission = new BlogPostSubmission { + Id = 1, + Content = "new content", + Title = "title" + }; + + var controller = new BlogController(logger, repo); + (await controller.SavePost(submission)).Should().BeOfType(); + } } } diff --git a/src/Robware.Api.Blog/Controllers/BlogController.cs b/src/Robware.Api.Blog/Controllers/BlogController.cs index d29addc..3b54d0b 100644 --- a/src/Robware.Api.Blog/Controllers/BlogController.cs +++ b/src/Robware.Api.Blog/Controllers/BlogController.cs @@ -3,6 +3,8 @@ using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; +using Newtonsoft.Json; +using Robware.Api.Blog.Models; using Robware.Blog; using Robware.Data; @@ -74,8 +76,24 @@ namespace Robware.Api.Blog.Controllers { } } - //[HttpPost] - //Task SavePost(BlogPost post); + [HttpPost(nameof(SavePost))] + public async Task SavePost(BlogPostSubmission submission) { + _logger.Log(LogLevel.Information, $"{nameof(SavePost)}: {nameof(submission)}={JsonConvert.SerializeObject(submission)}"); + + try { + var post = submission.Id.HasValue ? await _blogRepository.GetPostByIdAsync(submission.Id.Value) : new BlogPost(); + + post.UpdateTitle(submission.Title); + post.UpdateDraft(submission.Content); + + await _blogRepository.SavePost(post); + return Ok(); + } + catch (ItemNotFoundException e) { + _logger.Log(LogLevel.Error, e.Message); + return BadRequest("Tried to update post that doesn't exist"); + } + } //[HttpGet] //Task> GetAllPosts(); diff --git a/src/Robware.Api.Blog/Models/BlogPostSubmission.cs b/src/Robware.Api.Blog/Models/BlogPostSubmission.cs new file mode 100644 index 0000000..0f62db5 --- /dev/null +++ b/src/Robware.Api.Blog/Models/BlogPostSubmission.cs @@ -0,0 +1,7 @@ +namespace Robware.Api.Blog.Models { + public class BlogPostSubmission { + public int? Id { get; set; } + public string Title { get; set; } + public string Content { get; set; } + } +} \ No newline at end of file diff --git a/src/Robware.Api.Blog/Robware.Api.Blog.csproj b/src/Robware.Api.Blog/Robware.Api.Blog.csproj index 8ae137f..0a85bab 100644 --- a/src/Robware.Api.Blog/Robware.Api.Blog.csproj +++ b/src/Robware.Api.Blog/Robware.Api.Blog.csproj @@ -4,6 +4,10 @@ netcoreapp3.1 + + + + diff --git a/src/Robware.Data/BlogRepository.cs b/src/Robware.Data/BlogRepository.cs index fbe8abf..95fa0cd 100644 --- a/src/Robware.Data/BlogRepository.cs +++ b/src/Robware.Data/BlogRepository.cs @@ -80,7 +80,7 @@ namespace Robware.Data using (var connection = _dbProvider.NewConnection()) { connection.Open(); - var result = await DoQuery(connection, newPost ? newPostQuery : updatePostQuery, post); + var result = await connection.QueryAsync(newPost ? newPostQuery : updatePostQuery, post); return newPost ? await GetPostByIdAsync(result.Single()) : post; } }