Test blog controller
This commit is contained in:
parent
df01f4aa1d
commit
fcdec66861
2 changed files with 180 additions and 4 deletions
177
src/Website.Tests/Controllers/BlogControllerTests.cs
Normal file
177
src/Website.Tests/Controllers/BlogControllerTests.cs
Normal 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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,4 @@
|
||||||
using System;
|
using System.Linq;
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
@ -31,7 +30,7 @@ namespace Website.Controllers {
|
||||||
|
|
||||||
var model = new BlogPostViewModel(post, preview);
|
var model = new BlogPostViewModel(post, preview);
|
||||||
return View(model);
|
return View(model);
|
||||||
} catch (InvalidOperationException) {
|
} catch (ApiCallException) {
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,7 +48,7 @@ namespace Website.Controllers {
|
||||||
Content = post.Draft
|
Content = post.Draft
|
||||||
};
|
};
|
||||||
return View(model);
|
return View(model);
|
||||||
} catch (InvalidOperationException) {
|
} catch (ApiCallException) {
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue