Skip to content

Commit

Permalink
Refactor Web Part 2
Browse files Browse the repository at this point in the history
  • Loading branch information
linkdotnet committed Aug 31, 2024
1 parent fc33177 commit e71c7eb
Show file tree
Hide file tree
Showing 31 changed files with 239 additions and 115 deletions.
1 change: 1 addition & 0 deletions src/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
<AnalysisLevel>latest</AnalysisLevel>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
<NuGetAuditLevel>critical</NuGetAuditLevel>
<Nullable>enable</Nullable>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)' == 'Release'">
Expand Down
2 changes: 1 addition & 1 deletion src/LinkDotNet.Blog.Domain/Entity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@

public abstract class Entity
{
public string Id { get; set; } = string.Empty;
public string Id { get; set; } = default!;
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public CachedRepository(IRepository<T> repository, IMemoryCache memoryCache)

public ValueTask<HealthCheckResult> PerformHealthCheckAsync() => repository.PerformHealthCheckAsync();

public async ValueTask<T> GetByIdAsync(string id) =>
public async ValueTask<T?> GetByIdAsync(string id) =>
(await memoryCache.GetOrCreateAsync(id, async entry =>
{
entry.SlidingExpiration = TimeSpan.FromDays(7);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public interface IRepository<TEntity>
{
ValueTask<HealthCheckResult> PerformHealthCheckAsync();

ValueTask<TEntity> GetByIdAsync(string id);
ValueTask<TEntity?> GetByIdAsync(string id);

ValueTask<IPagedList<TEntity>> GetAllAsync(
Expression<Func<TEntity, bool>>? filter = null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ public sealed class Repository<TEntity> : IRepository<TEntity>

public ValueTask<HealthCheckResult> PerformHealthCheckAsync() => ValueTask.FromResult(HealthCheckResult.Healthy());

public ValueTask<TEntity> GetByIdAsync(string id)
public ValueTask<TEntity?> GetByIdAsync(string id)
{
var entity = entities.First(b => b.Id == id);
return new ValueTask<TEntity>(entity);
var entity = entities.Find(b => b.Id == id);
return new ValueTask<TEntity?>(entity);
}

public ValueTask<IPagedList<TEntity>> GetAllAsync(Expression<Func<TEntity, bool>>? filter = null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public async ValueTask<HealthCheckResult> PerformHealthCheckAsync()
}
}

public async ValueTask<TEntity> GetByIdAsync(string id)
public async ValueTask<TEntity?> GetByIdAsync(string id)
{
var filter = Builders<TEntity>.Filter.Eq(e => e.Id, id);
var result = await Collection.FindAsync(filter);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public async ValueTask<HealthCheckResult> PerformHealthCheckAsync()
}
}

public async ValueTask<TEntity> GetByIdAsync(string id)
public async ValueTask<TEntity?> GetByIdAsync(string id)
{
using var session = documentStore.OpenAsyncSession();
return await session.LoadAsync<TEntity>(id);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ public async ValueTask<HealthCheckResult> PerformHealthCheckAsync()
}
}

public async ValueTask<TEntity> GetByIdAsync(string id)
public async ValueTask<TEntity?> GetByIdAsync(string id)
{
var blogDbContext = await dbContextFactory.CreateDbContextAsync();
return await blogDbContext.Set<TEntity>().FirstAsync(b => b.Id == id);
return await blogDbContext.Set<TEntity>().FirstOrDefaultAsync(b => b.Id == id);
}

public ValueTask<IPagedList<TEntity>> GetAllAsync(Expression<Func<TEntity, bool>>? filter = null,
Expand Down
2 changes: 1 addition & 1 deletion src/LinkDotNet.Blog.Web/Features/Archive/ArchivePage.razor
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
</div>

@code {
private IReadOnlyCollection<IGrouping<int, BlogPostPerYear>> blogPostsPerYear = [];
private IReadOnlyCollection<IGrouping<int, BlogPostPerYear>>? blogPostsPerYear;
private int blogPostCount;

protected override async Task OnInitializedAsync()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,8 @@ else if (BlogPost is not null)

private async Task UpdateLikes(bool hasLiked)
{
BlogPost = await BlogPostRepository.GetByIdAsync(BlogPostId);
BlogPost = await BlogPostRepository.GetByIdAsync(BlogPostId)
?? throw new InvalidOperationException("Blog post not found");
BlogPost.Likes = hasLiked ? BlogPost.Likes + 1 : BlogPost.Likes - 1;
await BlogPostRepository.StoreAsync(BlogPost);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,9 @@ public async Task ShouldCreateRssFeed()
{
HttpContext = httpContext,
};
var config = Options.Create(new ApplicationConfiguration
{
BlogName = "Test"
});
var config = Options.Create(new ApplicationConfigurationBuilder()
.WithBlogName("Test")
.Build());

var introduction = new IntroductionBuilder()
.WithDescription("Description")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,19 +138,19 @@ public async Task ShouldSetPageToFirstIfOutOfRange(int? page)
cut.FindAll(".blog-card").Count.Should().Be(10);
}

private static (ApplicationConfiguration ApplicationConfiguration, Introduction Introduction) CreateSampleAppConfiguration(string profilePictureUri = null)
private static (ApplicationConfiguration ApplicationConfiguration, Introduction Introduction)
CreateSampleAppConfiguration(string profilePictureUri = null)
{
return (new ApplicationConfiguration
return (new ApplicationConfigurationBuilder()
.WithBlogName(string.Empty)
.WithBlogPostsPerPage(10)
.Build(),
new Introduction
{
BlogName = string.Empty,
BlogPostsPerPage = 10,
},
new Introduction
{
Description = string.Empty,
BackgroundUrl = string.Empty,
ProfilePictureUrl = profilePictureUri ?? string.Empty,
});
Description = string.Empty,
BackgroundUrl = string.Empty,
ProfilePictureUrl = profilePictureUri ?? string.Empty,
});
}

private async Task CreatePublishedBlogPosts(int amount)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ private void RegisterComponents(BunitContext ctx, ILocalStorageService localStor
ctx.Services.AddScoped(_ => localStorageService ?? Substitute.For<ILocalStorageService>());
ctx.Services.AddScoped(_ => Substitute.For<IToastService>());
ctx.Services.AddScoped(_ => Substitute.For<IUserRecordService>());
ctx.Services.AddScoped(_ => Options.Create(new ApplicationConfiguration()));
ctx.Services.AddScoped(_ => Options.Create(new ApplicationConfigurationBuilder().Build()));
ctx.Services.AddScoped(_ => Substitute.For<IInstantJobRegistry>());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public async Task ShouldCalculateSimilarBlogPosts()
await Repository.StoreAsync(blogPost1);
await Repository.StoreAsync(blogPost2);
await Repository.StoreAsync(blogPost3);
var config = Options.Create(new ApplicationConfiguration { ShowSimilarPosts = true });
var config = Options.Create(new ApplicationConfigurationBuilder().WithShowSimilarPosts(true).Build());

var job = new SimilarBlogPostJob(Repository, similarBlogPostRepository, config);
var context = Substitute.For<IJobExecutionContext>();
Expand All @@ -50,7 +50,7 @@ public async Task ShouldNotCalculateWhenDisabledInApplicationConfiguration()
await Repository.StoreAsync(blogPost1);
await Repository.StoreAsync(blogPost2);
await Repository.StoreAsync(blogPost3);
var config = Options.Create(new ApplicationConfiguration { ShowSimilarPosts = false });
var config = Options.Create(new ApplicationConfigurationBuilder().WithShowSimilarPosts(false).Build());

var job = new SimilarBlogPostJob(Repository, similarBlogPostRepository, config);
var context = Substitute.For<IJobExecutionContext>();
Expand All @@ -70,7 +70,7 @@ public async Task ShouldNotCalculateWhenNotTriggeredAsInstantJob()
await Repository.StoreAsync(blogPost1);
await Repository.StoreAsync(blogPost2);
await Repository.StoreAsync(blogPost3);
var config = Options.Create(new ApplicationConfiguration { ShowSimilarPosts = true });
var config = Options.Create(new ApplicationConfigurationBuilder().WithShowSimilarPosts(true).Build());

var job = new SimilarBlogPostJob(Repository, similarBlogPostRepository, config);
await job.RunAsync(Substitute.For<IJobExecutionContext>(), CancellationToken.None);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using LinkDotNet.Blog.Domain;
using LinkDotNet.Blog.Infrastructure.Persistence;
using LinkDotNet.Blog.TestUtilities;
using LinkDotNet.Blog.Web;
using LinkDotNet.Blog.Web.RegistrationExtensions;
using Microsoft.Extensions.DependencyInjection;
Expand All @@ -13,11 +14,10 @@ public class RavenDbRegistrationExtensionsTests
public void ShouldGetValidRepository()
{
var serviceCollection = new ServiceCollection();
var appConfig = Options.Create(new ApplicationConfiguration
{
ConnectionString = "http://localhost",
DatabaseName = "Blog",
});
var appConfig = Options.Create(new ApplicationConfigurationBuilder()
.WithBlogName("Blog")
.WithConnectionString("http://localhost")
.Build());
serviceCollection.AddScoped(_ => appConfig);

serviceCollection.UseRavenDbAsStorageProvider();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using LinkDotNet.Blog.Domain;
using LinkDotNet.Blog.Infrastructure.Persistence;
using LinkDotNet.Blog.TestUtilities;
using LinkDotNet.Blog.Web;
using LinkDotNet.Blog.Web.RegistrationExtensions;
using Microsoft.Extensions.Options;
Expand All @@ -13,10 +14,9 @@ public class SqliteRegistrationExtensionsTests
public void ShouldGetValidRepository()
{
var serviceCollection = new ServiceCollection();
var appConfig = Options.Create(new ApplicationConfiguration()
{
ConnectionString = "Filename=:memory:",
});
var appConfig = Options.Create(new ApplicationConfigurationBuilder()
.WithConnectionString("Filename=:memory:")
.Build());
serviceCollection.AddScoped(_ => appConfig);
serviceCollection.AddLogging();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Linq;
using LinkDotNet.Blog.Domain;
using LinkDotNet.Blog.Infrastructure.Persistence;
using LinkDotNet.Blog.TestUtilities;
using LinkDotNet.Blog.Web;
using LinkDotNet.Blog.Web.RegistrationExtensions;
using Microsoft.Extensions.Configuration;
Expand Down Expand Up @@ -48,7 +49,10 @@ public void ShouldHaveCacheRepositoryOnlyForBlogPosts()
var collection = new ServiceCollection();
var config = Substitute.For<IConfiguration>();
config["PersistenceProvider"].Returns("Sqlite");
collection.AddScoped(_ => Options.Create(new ApplicationConfiguration { ConnectionString = "Filename=:memory:" }));
collection.AddScoped(_ => Options.Create(new ApplicationConfigurationBuilder()
.WithConnectionString("Filename=:memory:")
.Build()));

collection.AddLogging();

collection.AddStorageProvider(config);
Expand Down
27 changes: 12 additions & 15 deletions tests/LinkDotNet.Blog.IntegrationTests/Web/Shared/NavMenuTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public NavMenuTests()
[Fact]
public void ShouldNavigateToSearchPage()
{
Services.AddScoped(_ => Options.Create(new ApplicationConfiguration()));
Services.AddScoped(_ => Options.Create(new ApplicationConfigurationBuilder().Build()));
AddAuthorization();
var navigationManager = Services.GetRequiredService<NavigationManager>();
var cut = Render<NavMenu>();
Expand All @@ -34,10 +34,9 @@ public void ShouldNavigateToSearchPage()
[Fact]
public void ShouldDisplayAboutMePage()
{
var config = Options.Create(new ApplicationConfiguration
{
IsAboutMeEnabled = true
});
var config = Options.Create(new ApplicationConfigurationBuilder()
.WithIsAboutMeEnabled(true)
.Build());
Services.AddScoped(_ => config);
AddAuthorization();

Expand Down Expand Up @@ -65,10 +64,9 @@ public void ShouldPassCorrectUriToComponent()
[Fact]
public void ShouldShowBrandImageIfAvailable()
{
var config = Options.Create(new ApplicationConfiguration
{
BlogBrandUrl = "http://localhost/img.png",
});
var config = Options.Create(new ApplicationConfigurationBuilder()
.WithBlogBrandUrl("http://localhost/img.png")
.Build());
Services.AddScoped(_ => config);

var profileInfoConfig = Options.Create(new ProfileInformationBuilder().Build());
Expand All @@ -89,11 +87,10 @@ public void ShouldShowBrandImageIfAvailable()
[InlineData("")]
public void ShouldShowBlogNameWhenNotBrand(string brandUrl)
{
var config = Options.Create(new ApplicationConfiguration
{
BlogBrandUrl = brandUrl,
BlogName = "Steven",
});
var config = Options.Create(new ApplicationConfigurationBuilder()
.WithBlogBrandUrl(brandUrl)
.WithBlogName("Steven")
.Build());
Services.AddScoped(_ => config);

var profileInfoConfig = Options.Create(new ProfileInformationBuilder().Build());
Expand All @@ -106,6 +103,6 @@ public void ShouldShowBlogNameWhenNotBrand(string brandUrl)
var brandImage = cut.Find(".nav-brand");
var image = brandImage as IHtmlAnchorElement;
image.Should().NotBeNull();
image.TextContent.Should().Be("Steven");
image!.TextContent.Should().Be("Steven");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public class ApplicationConfigurationBuilder
private bool showReadingIndicator;
private string? patreonName;
private bool showSimilarPosts;
private string? blogBrandUrl;

public ApplicationConfigurationBuilder WithBlogName(string blogName)
{
Expand Down Expand Up @@ -96,6 +97,12 @@ public ApplicationConfigurationBuilder WithShowSimilarPosts(bool showSimilarPost
return this;
}

public ApplicationConfigurationBuilder WithBlogBrandUrl(string blogBrandUrl)
{
this.blogBrandUrl = blogBrandUrl;
return this;
}

public ApplicationConfiguration Build()
{
return new ApplicationConfiguration
Expand All @@ -113,6 +120,7 @@ public ApplicationConfiguration Build()
ShowReadingIndicator = showReadingIndicator,
PatreonName = patreonName,
ShowSimilarPosts = showSimilarPosts,
BlogBrandUrl = blogBrandUrl,
};
}
}
46 changes: 46 additions & 0 deletions tests/LinkDotNet.Blog.TestUtilities/AuthInformationBuilder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using LinkDotNet.Blog.Web.Authentication.OpenIdConnect;

namespace LinkDotNet.Blog.TestUtilities;

public class AuthInformationBuilder
{
private string clientId = "clientId";
private string clientSecret = "client";
private string domain = "domain";
private string provider = "provider";

public AuthInformationBuilder WithClientId(string clientId)
{
this.clientId = clientId;
return this;
}

public AuthInformationBuilder WithClientSecret(string clientSecret)
{
this.clientSecret = clientSecret;
return this;
}

public AuthInformationBuilder WithDomain(string domain)
{
this.domain = domain;
return this;
}

public AuthInformationBuilder WithProvider(string provider)
{
this.provider = provider;
return this;
}

public AuthInformation Build()
{
return new AuthInformation
{
ClientId = clientId,
ClientSecret = clientSecret,
Domain = domain,
Provider = provider,
};
}
}
Loading

0 comments on commit e71c7eb

Please sign in to comment.