Test blog controller

This commit is contained in:
Robert Marshall 2020-04-13 13:01:14 +01:00
parent df01f4aa1d
commit fcdec66861
2 changed files with 180 additions and 4 deletions

View file

@ -0,0 +1,177 @@
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using FluentAssertions;
using Microsoft.AspNetCore.Mvc;
using NSubstitute;
using NSubstitute.ExceptionExtensions;
using Website.Controllers;
using Website.Data;
using Website.Models.Blog;
using Website.ViewModels.Blog;
using Xunit;
namespace Website.Tests.Controllers {
public class BlogControllerTests {
[Fact]
public async Task Page_WithPageNumber_ReturnsViewWithBlogPosts() {
var api = Substitute.For<IBlogApi>();
api.GetLatestPostsAsync(10, 10).Returns(new[] { new BlogPost { Content = "" } });
api.GetCountAsync().Returns(30);
var controller = new BlogController(api);
var expectation = new[] { new BlogPostSnippetViewModel(new BlogPost { Content = "" }) };
var model = (await controller.Page(2) as ViewResult).Model as BlogViewModel;
model.Page.Should().Be(2);
model.MaxPages.Should().Be(3);
model.Posts.Should().BeEquivalentTo(expectation);
}
[Fact]
public async Task Entry_WithUrlThatExists_ForPostWithContent_ReturnsViewWithBlogPost() {
var api = Substitute.For<IBlogApi>();
api.GetPostByUrlAsync("url").Returns(new BlogPost { Content = "c" });
var expectation = new BlogPostViewModel(new BlogPost { Content = "c" }, false);
var controller = new BlogController(api);
var result = await controller.Entry("url");
result.Should().BeOfType<ViewResult>();
(result as ViewResult).Model.Should().BeEquivalentTo(expectation);
}
[Fact]
public async Task Entry_WithUrlThatExists_ForPostWithoutContent_Returns404() {
var api = Substitute.For<IBlogApi>();
api.GetPostByUrlAsync("url").Returns(new BlogPost());
var controller = new BlogController(api);
(await controller.Entry("url")).Should().BeOfType<NotFoundResult>();
}
[Fact]
public async Task Entry_WithUrlThatExistsAndPreview_ForPostWithoutContent_ReturnsViewWithBlogPost() {
var api = Substitute.For<IBlogApi>();
api.GetPostByUrlAsync("url").Returns(new BlogPost { Draft = "" });
var expectation = new BlogPostViewModel(new BlogPost { Draft = "" }, true);
var controller = new BlogController(api);
var result = await controller.Entry("url", true);
result.Should().BeOfType<ViewResult>();
(result as ViewResult).Model.Should().BeEquivalentTo(expectation);
}
[Fact]
public async Task Entry_WithUrlThatDoesntExist_Returns404() {
var api = Substitute.For<IBlogApi>();
api.GetPostByUrlAsync("url")
.Throws(new ApiCallException(new HttpResponseMessage(HttpStatusCode.NotFound) {
RequestMessage = new HttpRequestMessage(HttpMethod.Get, new Uri("http://example.com/"))
}));
var controller = new BlogController(api);
(await controller.Entry("url")).Should().BeOfType<NotFoundResult>();
}
[Fact]
public async Task Edit_WithIdThatExists_ReturnsViewWithBlogPostSubmission() {
var api = Substitute.For<IBlogApi>();
api.GetPostByIdAsync(1).Returns(new BlogPost());
var expectation = new BlogPostSubmission {
Id = 0
};
var controller = new BlogController(api);
var result = await controller.Edit(1);
result.Should().BeOfType<ViewResult>();
(result as ViewResult).Model.Should().BeEquivalentTo(expectation);
}
[Fact]
public async Task Edit_WithIdThatDoesntExist_Returns404() {
var api = Substitute.For<IBlogApi>();
api.GetPostByIdAsync(1)
.Throws(new ApiCallException(new HttpResponseMessage(HttpStatusCode.NotFound) {
RequestMessage = new HttpRequestMessage(HttpMethod.Get, new Uri("http://example.com/"))
}));
var controller = new BlogController(api);
(await controller.Edit(1)).Should().BeOfType<NotFoundResult>();
}
[Fact]
public async Task Edit_WithNullId_ReturnsEmptyView() {
var api = Substitute.For<IBlogApi>();
var controller = new BlogController(api);
var result = await controller.Edit(null);
result.Should().BeOfType<ViewResult>();
(result as ViewResult).Model.Should().BeNull();
}
[Fact]
public async Task Save_WithSubmission_SavesPostAndRedirectsToEditPage() {
var api = Substitute.For<IBlogApi>();
var submission = new BlogPostSubmission();
api.SavePost(submission).Returns(new BlogPost { Id = 1 });
var controller = new BlogController(api);
var result = await controller.Save(submission);
result.Should().BeOfType<RedirectToActionResult>();
(result as RedirectToActionResult).ActionName.Should().Be("Edit");
(result as RedirectToActionResult).RouteValues.Should().Contain(new KeyValuePair<string, object>("id", 1));
}
[Fact]
public async Task Manage_ReturnsViewWithBlogPostsOrderedByDateDescending() {
var api = Substitute.For<IBlogApi>();
var posts = new[] {
new BlogPost{Timestamp = new DateTime(2020, 1, 2), Content= ""},
new BlogPost{Timestamp = new DateTime(2020, 1, 3), Content= ""},
new BlogPost{Timestamp = new DateTime(2020, 1, 1), Content= ""}
};
api.GetAllPostsAsync().Returns(posts);
var expectation = new[] {
new BlogPostViewModel(new BlogPost{Timestamp = new DateTime(2020, 1, 3), Content = ""}, false),
new BlogPostViewModel(new BlogPost{Timestamp = new DateTime(2020, 1, 2), Content = ""}, false),
new BlogPostViewModel(new BlogPost{Timestamp = new DateTime(2020, 1, 1), Content = ""}, false)
};
var controller = new BlogController(api);
var result = await controller.Manage();
result.Should().BeOfType<ViewResult>();
(result as ViewResult).Model.Should().BeEquivalentTo(expectation);
}
[Fact]
public async Task Publish_WithId_PublishesPostAndRedirectsToManagePage() {
var api = Substitute.For<IBlogApi>();
var controller = new BlogController(api);
var result = await controller.Publish(1);
await api.Received(1).PublishPostAsync(1);
result.Should().BeOfType<RedirectToActionResult>();
(result as RedirectToActionResult).ActionName.Should().Be("Manage");
}
[Fact]
public async Task Delete_WithId_DeletesPostAndRedirectsToManagePage() {
var api = Substitute.For<IBlogApi>();
var controller = new BlogController(api);
var result = await controller.Delete(1);
await api.Received(1).DeletePostAsync(1);
result.Should().BeOfType<RedirectToActionResult>();
(result as RedirectToActionResult).ActionName.Should().Be("Manage");
}
}
}

View file

@ -1,5 +1,4 @@
using System;
using System.Linq;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
@ -31,7 +30,7 @@ namespace Website.Controllers {
var model = new BlogPostViewModel(post, preview);
return View(model);
} catch (InvalidOperationException) {
} catch (ApiCallException) {
return NotFound();
}
}
@ -49,7 +48,7 @@ namespace Website.Controllers {
Content = post.Draft
};
return View(model);
} catch (InvalidOperationException) {
} catch (ApiCallException) {
return NotFound();
}
}