Skip to content

Commit ffd25f2

Browse files
committed
Refactored Create New BlogPost to own component for better create/update
1 parent 2b8a733 commit ffd25f2

File tree

7 files changed

+156
-87
lines changed

7 files changed

+156
-87
lines changed

LinkDotNet.Blog.IntegrationTests/SqlDatabaseTestBase.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,6 @@ namespace LinkDotNet.Blog.IntegrationTests
88
{
99
public abstract class SqlDatabaseTestBase : IAsyncLifetime, IAsyncDisposable
1010
{
11-
protected BlogPostRepository BlogPostRepository { get; private set; }
12-
13-
protected BlogPostContext DbContext { get; private set; }
14-
1511
protected SqlDatabaseTestBase()
1612
{
1713
var options = new DbContextOptionsBuilder()
@@ -21,6 +17,10 @@ protected SqlDatabaseTestBase()
2117
BlogPostRepository = new BlogPostRepository(new BlogPostContext(options));
2218
}
2319

20+
protected BlogPostRepository BlogPostRepository { get; private set; }
21+
22+
protected BlogPostContext DbContext { get; private set; }
23+
2424
public Task InitializeAsync()
2525
{
2626
return Task.CompletedTask;

LinkDotNet.Blog.UnitTests/LinkDotNet.Blog.UnitTests.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
</PropertyGroup>
88

99
<ItemGroup>
10+
<PackageReference Include="bunit" Version="1.2.36-preview" />
1011
<PackageReference Include="FluentAssertions" Version="5.10.3" />
1112
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="5.0.1" />
1213
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
@@ -31,6 +32,7 @@
3132
</ItemGroup>
3233

3334
<ItemGroup>
35+
<ProjectReference Include="..\LinkDotNet.Blog.TestUtilities\LinkDotNet.Blog.TestUtilities.csproj" />
3436
<ProjectReference Include="..\LinkDotNet.Blog.Web\LinkDotNet.Blog.Web.csproj" />
3537
</ItemGroup>
3638

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
using System.Linq;
2+
using Bunit;
3+
using FluentAssertions;
4+
using LinkDotNet.Blog.TestUtilities;
5+
using LinkDotNet.Blog.Web.Shared.Admin;
6+
using LinkDotNet.Domain;
7+
using Xunit;
8+
9+
namespace LinkDotNet.Blog.UnitTests.Web.Shared.Admin
10+
{
11+
public class CreateNewBlogPostTests
12+
{
13+
[Fact]
14+
public void ShouldCreateNewBlogPostWhenValidDataGiven()
15+
{
16+
using var ctx = new TestContext();
17+
BlogPost blogPost = null;
18+
var cut = ctx.RenderComponent<CreateNewBlogPost>(
19+
p => p.Add(c => c.OnBlogPostCreated, bp => blogPost = bp));
20+
cut.Find("#title").Change("My Title");
21+
cut.Find("#short").Change("My short Description");
22+
cut.Find("#content").Change("My content");
23+
cut.Find("#preview").Change("My preview url");
24+
cut.Find("#tags").Change("Tag1,Tag2,Tag3");
25+
26+
cut.Find("form").Submit();
27+
28+
cut.WaitForState(() => cut.Find("#title").TextContent == string.Empty);
29+
blogPost.Should().NotBeNull();
30+
blogPost.Title.Should().Be("My Title");
31+
blogPost.ShortDescription.Should().Be("My short Description");
32+
blogPost.Content.Should().Be("My content");
33+
blogPost.PreviewImageUrl.Should().Be("My preview url");
34+
blogPost.Tags.Should().HaveCount(3);
35+
blogPost.Tags.Select(t => t.Content).Should().Contain(new[] { "Tag1", "Tag2", "Tag3" });
36+
}
37+
38+
[Fact]
39+
public void ShouldFillGivenBlogPost()
40+
{
41+
using var ctx = new TestContext();
42+
var blogPost = new BlogPostBuilder().WithTitle("Title").WithShortDescription("Desc").WithContent("Content").Build();
43+
BlogPost blogPostFromComponent = null;
44+
var cut = ctx.RenderComponent<CreateNewBlogPost>(
45+
p =>
46+
p.Add(c => c.OnBlogPostCreated, bp => blogPostFromComponent = bp)
47+
.Add(c => c.BlogPost, blogPost));
48+
cut.Find("#title").Change("My new Title");
49+
50+
cut.Find("form").Submit();
51+
52+
cut.WaitForState(() => cut.Find("#title").TextContent == string.Empty);
53+
blogPostFromComponent.Should().NotBeNull();
54+
blogPostFromComponent.Title.Should().Be("My new Title");
55+
blogPostFromComponent.ShortDescription.Should().Be("Desc");
56+
blogPostFromComponent.Content.Should().Be("Content");
57+
}
58+
}
59+
}
Lines changed: 6 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,93 +1,18 @@
11
@page "/CreateNew"
2-
@page "/CreateNew/{blogPostId}"
32
@attribute [Authorize]
43
@using LinkDotNet.Infrastructure.Persistence
4+
@using LinkDotNet.Blog.Web.Shared.Admin
55
@using LinkDotNet.Domain
66
@inherits MarkdownComponentBase
77
@inject IRepository _repository
88
@inject IToastService _toastService
9-
<h3>Create new Blog Post</h3>
109

11-
<div class="content-area">
12-
<div class="new-content">
13-
<EditForm Model="@_model" OnValidSubmit="SaveBlogPostAsync">
14-
<DataAnnotationsValidator />
15-
<ValidationSummary />
16-
<div class="form-group">
17-
<label for="title">Title</label>
18-
<InputText class="form-control" id="title" @bind-Value="_model.Title" />
19-
</div>
20-
<div class="form-group">
21-
<label for="short">Short Description</label>
22-
<InputTextArea class="form-control" id="short" @bind-Value="_model.ShortDescription" rows="4"/>
23-
</div>
24-
<div class="form-group">
25-
<label for="content">Content</label>
26-
<InputTextArea class="form-control" id="content" @bind-Value="_model.Content" rows="10" />
27-
@* <small id="content" class="form-text text-muted">Drag and drop images to upload and insert picture.</small> *@
28-
</div>
29-
<div class="form-group">
30-
<label for="preview">Preview-Url</label>
31-
<InputText class="form-control" id="preview" @bind-Value="_model.PreviewImageUrl"/>
32-
</div>
33-
<div class="form-group">
34-
<label for="tags">Tags</label>
35-
<InputText class="form-control" id="tags" @bind-Value="_model.Tags"/>
36-
</div>
37-
38-
<button class="btn btn-primary" type="submit">Submit</button>
39-
40-
</EditForm>
41-
</div>
42-
<div class="preview">
43-
<div>
44-
<header>
45-
<h1>@_model.Title</h1>
46-
</header>
47-
<div>
48-
@(RenderMarkupString(_model.ShortDescription))
49-
</div>
50-
<div>
51-
@(RenderMarkupString(_model.Content))
52-
</div>
53-
</div>
54-
</div>
55-
</div>
56-
@code {
57-
[Parameter]
58-
public string BlogPostId { get; set; }
59-
60-
private CreateNewModel _model = new();
61-
private BlogPost _blogPost;
62-
63-
protected override async Task OnParametersSetAsync()
64-
{
65-
if (string.IsNullOrEmpty(BlogPostId))
66-
{
67-
return;
68-
}
10+
<CreateNewBlogPost Title="Create new BlogPost" OnBlogPostCreated="@(blogPost => StoreBlogPostAsync(blogPost))" ></CreateNewBlogPost>
6911

70-
_blogPost = await _repository.GetByIdAsync(BlogPostId);
71-
_model = CreateNewModel.FromBlogPost(_blogPost);
72-
}
73-
74-
private async Task SaveBlogPostAsync()
75-
{
76-
//// Does not work when updating
77-
await _repository.StoreAsync(_model.ToBlogPost());
78-
DisplayMessage();
79-
ClearModel();
80-
}
81-
82-
private void DisplayMessage()
83-
{
84-
var operationInformation = BlogPostId == null ? "Created" : "Updated";
85-
_toastService.ShowSuccess($"{operationInformation} BlogPost {_model.Title}");
86-
}
87-
88-
private void ClearModel()
12+
@code {
13+
private async Task StoreBlogPostAsync(BlogPost blogPost)
8914
{
90-
_model = new CreateNewModel();
15+
await _repository.StoreAsync(blogPost);
16+
_toastService.ShowInfo($"Created BlogPost {blogPost.Title}");
9117
}
92-
9318
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
@using LinkDotNet.Domain
2+
@inherits MarkdownComponentBase
3+
4+
<h3>@Title</h3>
5+
6+
<div class="content-area">
7+
<div class="new-content">
8+
<EditForm Model="@_model" OnValidSubmit="OnValidBlogPostCreatedAsync">
9+
<DataAnnotationsValidator />
10+
<ValidationSummary />
11+
<div class="form-group">
12+
<label for="title">Title</label>
13+
<InputText class="form-control" id="title" @bind-Value="_model.Title" />
14+
</div>
15+
<div class="form-group">
16+
<label for="short">Short Description</label>
17+
<InputTextArea class="form-control" id="short" @bind-Value="_model.ShortDescription" rows="4"/>
18+
</div>
19+
<div class="form-group">
20+
<label for="content">Content</label>
21+
<InputTextArea class="form-control" id="content" @bind-Value="_model.Content" rows="10" />
22+
@* <small id="content" class="form-text text-muted">Drag and drop images to upload and insert picture.</small> *@
23+
</div>
24+
<div class="form-group">
25+
<label for="preview">Preview-Url</label>
26+
<InputText class="form-control" id="preview" @bind-Value="_model.PreviewImageUrl"/>
27+
</div>
28+
<div class="form-group">
29+
<label for="tags">Tags</label>
30+
<InputText class="form-control" id="tags" @bind-Value="_model.Tags"/>
31+
</div>
32+
33+
<button class="btn btn-primary" type="submit">Submit</button>
34+
35+
</EditForm>
36+
</div>
37+
<div class="preview">
38+
<div>
39+
<header>
40+
<h1>@_model.Title</h1>
41+
</header>
42+
<div>
43+
@(RenderMarkupString(_model.ShortDescription))
44+
</div>
45+
<div>
46+
@(RenderMarkupString(_model.Content))
47+
</div>
48+
</div>
49+
</div>
50+
</div>
51+
@code {
52+
[Parameter]
53+
public BlogPost BlogPost { get; set; }
54+
55+
[Parameter]
56+
public string Title { get; set; }
57+
58+
[Parameter]
59+
public EventCallback<BlogPost> OnBlogPostCreated { get; set; }
60+
61+
private CreateNewModel _model = new();
62+
63+
protected override void OnParametersSet()
64+
{
65+
if (BlogPost == null)
66+
{
67+
return;
68+
}
69+
70+
_model = CreateNewModel.FromBlogPost(BlogPost);
71+
}
72+
73+
private async Task OnValidBlogPostCreatedAsync()
74+
{
75+
await OnBlogPostCreated.InvokeAsync(_model.ToBlogPost());
76+
ClearModel();
77+
}
78+
79+
private void ClearModel()
80+
{
81+
_model = new CreateNewModel();
82+
}
83+
}

LinkDotNet.Blog.Web/Pages/Admin/CreateNew.razor.css renamed to LinkDotNet.Blog.Web/Shared/Admin/CreateNewBlogPost.razor.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
.content-area {
1+
.content-area {
22
margin-left: 20px;
33
margin-right: 20px;
44
display: flex;

LinkDotNet.Blog.Web/Pages/Admin/CreateNewModel.cs renamed to LinkDotNet.Blog.Web/Shared/Admin/CreateNewModel.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
using System.Linq;
44
using LinkDotNet.Domain;
55

6-
namespace LinkDotNet.Blog.Web.Pages.Admin
6+
namespace LinkDotNet.Blog.Web.Shared.Admin
77
{
88
public class CreateNewModel
99
{

0 commit comments

Comments
 (0)