From b964fa3736591a74b7f35de4dd0d3b9d207e931d Mon Sep 17 00:00:00 2001 From: Peter van den Hout Date: Mon, 6 Sep 2021 15:34:15 +0200 Subject: [PATCH] GitDb BlogSettingsConfigurationProvider #131 (#136) --- azure-pipelines.yml | 10 ++++ .../appsettings.json | 2 +- .../BlogSettingsConfigurationProvider.cs | 1 - src/Opw.PineBlog.GitDb/GitDbSyncService.cs | 17 ++++++ src/Opw.PineBlog.GitDb/InternalsVisibleTo.cs | 2 + .../Opw.PineBlog.GitDb.csproj | 2 +- src/Opw.PineBlog.GitDb/PathHelper.cs | 1 - .../BlogSettingsConfigurationProviderTests.cs | 55 +++++++++++++++++++ tests/Opw.PineBlog.GitDb.Tests/Constants.cs | 8 +++ .../LibGit2/GitDbContextTests.cs | 21 ++++++- .../PathHelperTests.cs | 32 +++++++++++ 11 files changed, 145 insertions(+), 6 deletions(-) create mode 100644 src/Opw.PineBlog.GitDb/InternalsVisibleTo.cs create mode 100644 tests/Opw.PineBlog.GitDb.Tests/BlogSettingsConfigurationProviderTests.cs create mode 100644 tests/Opw.PineBlog.GitDb.Tests/Constants.cs create mode 100644 tests/Opw.PineBlog.GitDb.Tests/PathHelperTests.cs diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 8d50614..c3bdaa0 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -127,6 +127,16 @@ steps: versioningScheme: byEnvVar versionEnvVar: 'GitVersion.NuGetVersion' +- task: DotNetCoreCLI@2 + displayName: NuGet Pack Opw.PineBlog.GitDb + condition: and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/tags/')) + inputs: + command: pack + packagesToPack: '**/Opw.PineBlog.GitDb.csproj' + nobuild: true + versioningScheme: byEnvVar + versionEnvVar: 'GitVersion.NuGetVersion' + - task: DotNetCoreCLI@2 displayName: NuGet Pack Opw.PineBlog condition: and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/tags/')) diff --git a/samples/Opw.PineBlog.Sample.GitDb/appsettings.json b/samples/Opw.PineBlog.Sample.GitDb/appsettings.json index 8b52d5d..5ee4bc7 100644 --- a/samples/Opw.PineBlog.Sample.GitDb/appsettings.json +++ b/samples/Opw.PineBlog.Sample.GitDb/appsettings.json @@ -16,7 +16,7 @@ "RepositoryUrl": "https://github.com/ofpinewood/pineblog-gitdb.git", "Branch": "test", "RootPath": "pineblog", - "SyncFrequency": 300 + "SyncFrequency": 180 }, "Logging": { "LogLevel": { diff --git a/src/Opw.PineBlog.GitDb/BlogSettingsConfigurationProvider.cs b/src/Opw.PineBlog.GitDb/BlogSettingsConfigurationProvider.cs index 85ad53f..37df32f 100644 --- a/src/Opw.PineBlog.GitDb/BlogSettingsConfigurationProvider.cs +++ b/src/Opw.PineBlog.GitDb/BlogSettingsConfigurationProvider.cs @@ -10,7 +10,6 @@ namespace Opw.PineBlog.GitDb { - // TODO: add tests /// /// Provides blog settings configuration key/values for the application. /// diff --git a/src/Opw.PineBlog.GitDb/GitDbSyncService.cs b/src/Opw.PineBlog.GitDb/GitDbSyncService.cs index fa0a58b..c9663e5 100644 --- a/src/Opw.PineBlog.GitDb/GitDbSyncService.cs +++ b/src/Opw.PineBlog.GitDb/GitDbSyncService.cs @@ -48,6 +48,8 @@ private void Sync(object state) var branchesSynced = context.Sync(); if (branchesSynced < 1) _logger.LogError($"Could not sync repository \"{_options.Value.RepositoryUrl}\"."); + + CheckBlogSettingsFileChanges(context); } } catch (Exception ex) @@ -60,6 +62,21 @@ private void Sync(object state) _logger.LogInformation($"GitDbSyncService: \"{_options.Value.RepositoryUrl}\" synced."); } + private void CheckBlogSettingsFileChanges(GitDbContext context) + { + var path = PathHelper.Build(_options.Value.LocalRepositoryBasePath, _options.Value.RootPath, GitDbConstants.BlogSettingsFile); + if (!File.Exists(path)) + return; + + var lastModifiedDate = File.GetLastWriteTimeUtc(path); + if (lastModifiedDate != null && lastModifiedDate > DateTime.UtcNow.AddSeconds(-10)) + { + path = PathHelper.Build(_options.Value.RootPath, GitDbConstants.BlogSettingsFile); + var files = context.GetFiles(new string[] { path }); + FileChangeObserver.Instance.OnChanged(new FileChangeEventArgs(GitDbConstants.BlogSettingsFile, files[path])); + } + } + public Task StopAsync(CancellationToken cancellationToken) { _logger.LogInformation("GitDbSyncService: Hosted Service is stopping."); diff --git a/src/Opw.PineBlog.GitDb/InternalsVisibleTo.cs b/src/Opw.PineBlog.GitDb/InternalsVisibleTo.cs new file mode 100644 index 0000000..d011934 --- /dev/null +++ b/src/Opw.PineBlog.GitDb/InternalsVisibleTo.cs @@ -0,0 +1,2 @@ +using System.Runtime.CompilerServices; +[assembly: InternalsVisibleTo("Opw.PineBlog.GitDb.Tests")] diff --git a/src/Opw.PineBlog.GitDb/Opw.PineBlog.GitDb.csproj b/src/Opw.PineBlog.GitDb/Opw.PineBlog.GitDb.csproj index 9d7f373..c90a68d 100644 --- a/src/Opw.PineBlog.GitDb/Opw.PineBlog.GitDb.csproj +++ b/src/Opw.PineBlog.GitDb/Opw.PineBlog.GitDb.csproj @@ -5,7 +5,7 @@ PineBlog data provider that uses a Git repository. true Opw.PineBlog.Git - blog git + blog gitdb git diff --git a/src/Opw.PineBlog.GitDb/PathHelper.cs b/src/Opw.PineBlog.GitDb/PathHelper.cs index 163bcca..a140872 100644 --- a/src/Opw.PineBlog.GitDb/PathHelper.cs +++ b/src/Opw.PineBlog.GitDb/PathHelper.cs @@ -2,7 +2,6 @@ namespace Opw.PineBlog.GitDb { - // TODO: add tests internal static class PathHelper { internal static string Build(params string[] parts) diff --git a/tests/Opw.PineBlog.GitDb.Tests/BlogSettingsConfigurationProviderTests.cs b/tests/Opw.PineBlog.GitDb.Tests/BlogSettingsConfigurationProviderTests.cs new file mode 100644 index 0000000..8cb1edb --- /dev/null +++ b/tests/Opw.PineBlog.GitDb.Tests/BlogSettingsConfigurationProviderTests.cs @@ -0,0 +1,55 @@ +using Xunit; +using Microsoft.Extensions.DependencyInjection; +using FluentAssertions; +using Microsoft.Extensions.Options; + +namespace Opw.PineBlog.GitDb +{ + public class BlogSettingsConfigurationProviderTests : GitDbTestsBase + { + private readonly IOptions _options; + private readonly BlogSettingsConfigurationProvider _provider; + + public BlogSettingsConfigurationProviderTests(GitDbFixture fixture) : base(fixture) + { + _options = ServiceProvider.GetRequiredService>(); + + _provider = new BlogSettingsConfigurationProvider(new BlogSettingsConfigurationSource + { + Options = _options.Value, + ReloadOnChange = true + }); + } + + [Fact(Skip = Constants.SkipGitDbBlogSettingsConfigurationProviderTests)] + public void Load_Should_HaveSettings() + { + _provider.Load(); + + _provider.TryGet($"{nameof(PineBlogOptions)}:{nameof(PineBlogOptions.Title)}", out var title); + _provider.TryGet($"{nameof(PineBlogOptions)}:{nameof(PineBlogOptions.Description)}", out var description); + + title.Should().Be("PineBlog"); + description.Should().Be("A blogging engine based on ASP.NET Core MVC Razor Pages and Entity Framework Core"); + } + + [Fact(Skip = Constants.SkipGitDbBlogSettingsConfigurationProviderTests)] + public void Load_Should_NotHaveSettings() + { + var options = _options.Value; + options.RootPath = "invalid"; + + var provider = new BlogSettingsConfigurationProvider(new BlogSettingsConfigurationSource + { + Options = _options.Value, + ReloadOnChange = true + }); + + provider.Load(); + + provider.TryGet($"{nameof(PineBlogOptions)}:{nameof(PineBlogOptions.Title)}", out var title); + + title.Should().BeNull(); + } + } +} diff --git a/tests/Opw.PineBlog.GitDb.Tests/Constants.cs b/tests/Opw.PineBlog.GitDb.Tests/Constants.cs new file mode 100644 index 0000000..24a01c1 --- /dev/null +++ b/tests/Opw.PineBlog.GitDb.Tests/Constants.cs @@ -0,0 +1,8 @@ + +namespace Opw.PineBlog.GitDb +{ + public static class Constants + { + public const string SkipGitDbBlogSettingsConfigurationProviderTests = null;//"These tests do not work on the build server."; + } +} diff --git a/tests/Opw.PineBlog.GitDb.Tests/LibGit2/GitDbContextTests.cs b/tests/Opw.PineBlog.GitDb.Tests/LibGit2/GitDbContextTests.cs index 88e8c5d..30bb4ab 100644 --- a/tests/Opw.PineBlog.GitDb.Tests/LibGit2/GitDbContextTests.cs +++ b/tests/Opw.PineBlog.GitDb.Tests/LibGit2/GitDbContextTests.cs @@ -9,12 +9,29 @@ namespace Opw.PineBlog.GitDb.LibGit2 { public class GitDbContextTests : GitDbTestsBase { + private readonly IOptions _options; private readonly GitDbContext _gitDbContext; public GitDbContextTests(GitDbFixture fixture) : base(fixture) { - var options = ServiceProvider.GetService>(); - _gitDbContext = GitDbContext.Create(options.Value); + _options = ServiceProvider.GetService>(); + _gitDbContext = GitDbContext.Create(_options.Value); + } + + [Fact] + public void Create_Default_GitDbContext() + { + var gitDbContext = GitDbContext.Create(_options.Value); + + gitDbContext.Should().NotBeNull(); + } + + [Fact] + public void CreateFromLocal_Default_GitDbContext() + { + var gitDbContext = GitDbContext.CreateFromLocal(_options.Value); + + gitDbContext.Should().NotBeNull(); } [Fact] diff --git a/tests/Opw.PineBlog.GitDb.Tests/PathHelperTests.cs b/tests/Opw.PineBlog.GitDb.Tests/PathHelperTests.cs new file mode 100644 index 0000000..acba62c --- /dev/null +++ b/tests/Opw.PineBlog.GitDb.Tests/PathHelperTests.cs @@ -0,0 +1,32 @@ +using FluentAssertions; +using Xunit; + +namespace Opw.PineBlog.GitDb +{ + public class PathHelperTests + { + [Fact] + public void Build_Should_ReturnPath() + { + var result = PathHelper.Build("A", "B", "C"); + + result.Should().Be("A/B/C"); + } + + [Fact] + public void Build_Should_TrimSlashes() + { + var result = PathHelper.Build("/A", "\\B", "C"); + + result.Should().Be("A/B/C"); + } + + [Fact] + public void Build_Should_IgnoreWhiteSpaceParts() + { + var result = PathHelper.Build("A", " ", "", null, "B", "C"); + + result.Should().Be("A/B/C"); + } + } +}