Fix smidge bundles not always invalidated between backoffice versions. (#11700)
* Introduced new smidge CacheBuster with sensible defaults. * Bring back reset functionality in SmidgeRuntimeMinifier * Clearer obsolete messaging.
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -84,6 +84,7 @@ src/Umbraco.Web.UI/wwwroot/[Uu]mbraco/js/*
|
|||||||
src/Umbraco.Web.UI/wwwroot/[Uu]mbraco/lib/*
|
src/Umbraco.Web.UI/wwwroot/[Uu]mbraco/lib/*
|
||||||
src/Umbraco.Web.UI/wwwroot/[Uu]mbraco/views/*
|
src/Umbraco.Web.UI/wwwroot/[Uu]mbraco/views/*
|
||||||
src/Umbraco.Web.UI/wwwroot/Media/*
|
src/Umbraco.Web.UI/wwwroot/Media/*
|
||||||
|
src/Umbraco.Web.UI/Smidge/
|
||||||
|
|
||||||
# Tests
|
# Tests
|
||||||
cypress.env.json
|
cypress.env.json
|
||||||
|
|||||||
24
src/Umbraco.Core/Configuration/EntryAssemblyMetadata.cs
Normal file
24
src/Umbraco.Core/Configuration/EntryAssemblyMetadata.cs
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace Umbraco.Cms.Core.Configuration
|
||||||
|
{
|
||||||
|
internal class EntryAssemblyMetadata : IEntryAssemblyMetadata
|
||||||
|
{
|
||||||
|
public EntryAssemblyMetadata()
|
||||||
|
{
|
||||||
|
var entryAssembly = Assembly.GetEntryAssembly();
|
||||||
|
|
||||||
|
Name = entryAssembly
|
||||||
|
?.GetName()
|
||||||
|
?.Name ?? string.Empty;
|
||||||
|
|
||||||
|
InformationalVersion = entryAssembly
|
||||||
|
?.GetCustomAttribute<AssemblyInformationalVersionAttribute>()
|
||||||
|
?.InformationalVersion ?? string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Name { get; }
|
||||||
|
|
||||||
|
public string InformationalVersion { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
18
src/Umbraco.Core/Configuration/IEntryAssemblyMetadata.cs
Normal file
18
src/Umbraco.Core/Configuration/IEntryAssemblyMetadata.cs
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
namespace Umbraco.Cms.Core.Configuration
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Provides metadata about the entry assembly.
|
||||||
|
/// </summary>
|
||||||
|
public interface IEntryAssemblyMetadata
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the Name of entry assembly.
|
||||||
|
/// </summary>
|
||||||
|
public string Name { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the InformationalVersion string for entry assembly.
|
||||||
|
/// </summary>
|
||||||
|
public string InformationalVersion { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -163,6 +163,7 @@ namespace Umbraco.Cms.Core.DependencyInjection
|
|||||||
Services.AddUnique(factory => factory.GetRequiredService<AppCaches>().RequestCache);
|
Services.AddUnique(factory => factory.GetRequiredService<AppCaches>().RequestCache);
|
||||||
Services.AddUnique<IProfilingLogger, ProfilingLogger>();
|
Services.AddUnique<IProfilingLogger, ProfilingLogger>();
|
||||||
Services.AddUnique<IUmbracoVersion, UmbracoVersion>();
|
Services.AddUnique<IUmbracoVersion, UmbracoVersion>();
|
||||||
|
Services.AddUnique<IEntryAssemblyMetadata, EntryAssemblyMetadata>();
|
||||||
|
|
||||||
this.AddAllCoreCollectionBuilders();
|
this.AddAllCoreCollectionBuilders();
|
||||||
this.AddNotificationHandler<UmbracoApplicationStartingNotification, EssentialDirectoryCreator>();
|
this.AddNotificationHandler<UmbracoApplicationStartingNotification, EssentialDirectoryCreator>();
|
||||||
|
|||||||
@@ -88,7 +88,18 @@ namespace Umbraco.Cms.Core.WebAssets
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Ensures that all runtime minifications are refreshed on next request. E.g. Clearing cache.
|
/// Ensures that all runtime minifications are refreshed on next request. E.g. Clearing cache.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// <para>
|
||||||
|
/// No longer necessary, invalidation occurs automatically if any of the following occur.
|
||||||
|
/// </para>
|
||||||
|
/// <list type="bullet">
|
||||||
|
/// <item>Your sites assembly information version changes.</item>
|
||||||
|
/// <item>Umbraco.Cms.Core assembly information version changes.</item>
|
||||||
|
/// <item>RuntimeMinificationSettings Version string changes.</item>
|
||||||
|
/// </list>
|
||||||
|
/// <see href="https://our.umbraco.com/documentation/Reference/V9-Config/RuntimeMinificationSettings/" /> for further details.
|
||||||
|
/// </remarks>
|
||||||
|
[Obsolete("Invalidation is handled automatically. Scheduled for removal V11.")]
|
||||||
void Reset();
|
void Reset();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,9 +72,6 @@ namespace Umbraco.Cms.Web.BackOffice.Install
|
|||||||
// TODO: Update for package migrations
|
// TODO: Update for package migrations
|
||||||
if (_runtime.Level == RuntimeLevel.Upgrade)
|
if (_runtime.Level == RuntimeLevel.Upgrade)
|
||||||
{
|
{
|
||||||
// Update ClientDependency version and delete its temp directories to make sure we get fresh caches
|
|
||||||
_runtimeMinifier.Reset();
|
|
||||||
|
|
||||||
var authResult = await this.AuthenticateBackOfficeAsync();
|
var authResult = await this.AuthenticateBackOfficeAsync();
|
||||||
|
|
||||||
if (!authResult.Succeeded)
|
if (!authResult.Succeeded)
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ using Microsoft.Extensions.Hosting;
|
|||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
using Smidge;
|
using Smidge;
|
||||||
|
using Smidge.Cache;
|
||||||
using Smidge.FileProcessors;
|
using Smidge.FileProcessors;
|
||||||
using Smidge.InMemory;
|
using Smidge.InMemory;
|
||||||
using Smidge.Nuglify;
|
using Smidge.Nuglify;
|
||||||
@@ -274,6 +275,7 @@ namespace Umbraco.Extensions
|
|||||||
new[] { "/App_Plugins/**/*.js", "/App_Plugins/**/*.css" }));
|
new[] { "/App_Plugins/**/*.js", "/App_Plugins/**/*.css" }));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
builder.Services.AddUnique<ICacheBuster, UmbracoSmidgeConfigCacheBuster>();
|
||||||
builder.Services.AddSmidge(builder.Config.GetSection(Constants.Configuration.ConfigRuntimeMinification));
|
builder.Services.AddSmidge(builder.Config.GetSection(Constants.Configuration.ConfigRuntimeMinification));
|
||||||
// Replace the Smidge request helper, in order to discourage the use of brotli since it's super slow
|
// Replace the Smidge request helper, in order to discourage the use of brotli since it's super slow
|
||||||
builder.Services.AddUnique<IRequestHelper, SmidgeRequestHelper>();
|
builder.Services.AddUnique<IRequestHelper, SmidgeRequestHelper>();
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ namespace Umbraco.Cms.Web.Common.RuntimeMinification
|
|||||||
private readonly IHostingEnvironment _hostingEnvironment;
|
private readonly IHostingEnvironment _hostingEnvironment;
|
||||||
private readonly IConfigManipulator _configManipulator;
|
private readonly IConfigManipulator _configManipulator;
|
||||||
private readonly CacheBusterResolver _cacheBusterResolver;
|
private readonly CacheBusterResolver _cacheBusterResolver;
|
||||||
private readonly RuntimeMinificationSettings _runtimeMinificationSettings;
|
|
||||||
private readonly IBundleManager _bundles;
|
private readonly IBundleManager _bundles;
|
||||||
private readonly SmidgeHelperAccessor _smidge;
|
private readonly SmidgeHelperAccessor _smidge;
|
||||||
|
|
||||||
@@ -53,7 +52,6 @@ namespace Umbraco.Cms.Web.Common.RuntimeMinification
|
|||||||
_hostingEnvironment = hostingEnvironment;
|
_hostingEnvironment = hostingEnvironment;
|
||||||
_configManipulator = configManipulator;
|
_configManipulator = configManipulator;
|
||||||
_cacheBusterResolver = cacheBusterResolver;
|
_cacheBusterResolver = cacheBusterResolver;
|
||||||
_runtimeMinificationSettings = runtimeMinificationSettings.Value;
|
|
||||||
_jsMinPipeline = new Lazy<PreProcessPipeline>(() => _bundles.PipelineFactory.Create(typeof(JsMinifier)));
|
_jsMinPipeline = new Lazy<PreProcessPipeline>(() => _bundles.PipelineFactory.Create(typeof(JsMinifier)));
|
||||||
_cssMinPipeline = new Lazy<PreProcessPipeline>(() => _bundles.PipelineFactory.Create(typeof(NuglifyCss)));
|
_cssMinPipeline = new Lazy<PreProcessPipeline>(() => _bundles.PipelineFactory.Create(typeof(NuglifyCss)));
|
||||||
|
|
||||||
@@ -76,10 +74,10 @@ namespace Umbraco.Cms.Web.Common.RuntimeMinification
|
|||||||
return defaultCss;
|
return defaultCss;
|
||||||
});
|
});
|
||||||
|
|
||||||
Type cacheBusterType = _runtimeMinificationSettings.CacheBuster switch
|
Type cacheBusterType = runtimeMinificationSettings.Value.CacheBuster switch
|
||||||
{
|
{
|
||||||
RuntimeMinificationCacheBuster.AppDomain => typeof(AppDomainLifetimeCacheBuster),
|
RuntimeMinificationCacheBuster.AppDomain => typeof(AppDomainLifetimeCacheBuster),
|
||||||
RuntimeMinificationCacheBuster.Version => typeof(ConfigCacheBuster),
|
RuntimeMinificationCacheBuster.Version => typeof(UmbracoSmidgeConfigCacheBuster),
|
||||||
RuntimeMinificationCacheBuster.Timestamp => typeof(TimestampCacheBuster),
|
RuntimeMinificationCacheBuster.Timestamp => typeof(TimestampCacheBuster),
|
||||||
_ => throw new NotImplementedException()
|
_ => throw new NotImplementedException()
|
||||||
};
|
};
|
||||||
@@ -169,18 +167,12 @@ namespace Umbraco.Cms.Web.Common.RuntimeMinification
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
/// <remarks>
|
[Obsolete("Invalidation is handled automatically. Scheduled for removal V11.")]
|
||||||
/// Smidge uses the version number as cache buster (configurable).
|
|
||||||
/// We therefore can reset, by updating the version number in config
|
|
||||||
/// </remarks>
|
|
||||||
public void Reset()
|
public void Reset()
|
||||||
{
|
{
|
||||||
var version = DateTime.UtcNow.Ticks.ToString();
|
var version = DateTime.UtcNow.Ticks.ToString();
|
||||||
_configManipulator.SaveConfigValue(Cms.Core.Constants.Configuration.ConfigRuntimeMinificationVersion, version.ToString());
|
_configManipulator.SaveConfigValue(Cms.Core.Constants.Configuration.ConfigRuntimeMinificationVersion, version.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using Smidge;
|
||||||
|
using Smidge.Cache;
|
||||||
|
using Umbraco.Cms.Core.Configuration;
|
||||||
|
using Umbraco.Cms.Core.Configuration.Models;
|
||||||
|
using Umbraco.Extensions;
|
||||||
|
|
||||||
|
namespace Umbraco.Cms.Web.Common.RuntimeMinification
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Constructs a cache buster string with sensible defaults.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// <para>
|
||||||
|
/// Had planned on handling all of this in SmidgeRuntimeMinifier, but that only handles some urls.
|
||||||
|
/// </para>
|
||||||
|
/// <para>
|
||||||
|
/// A lot of the work is delegated e.g. to <see cref="SmidgeHelper.GenerateJsUrlsAsync(string, bool)"/>
|
||||||
|
/// which doesn't care about the cache buster string in our classes only the value returned by the resolved ICacheBuster.
|
||||||
|
/// </para>
|
||||||
|
/// <para>
|
||||||
|
/// Then I thought fine I'll just use a IConfigureOptions to tweak upstream <see cref="ConfigCacheBuster"/>, but that only cares about the <see cref="SmidgeConfig"/>
|
||||||
|
/// class we instantiate and pass through in <see cref="Umbraco.Extensions.UmbracoBuilderExtensions.AddRuntimeMinifier"/>
|
||||||
|
/// </para>
|
||||||
|
/// <para>
|
||||||
|
/// So here we are, create our own to ensure we cache bust in a reasonable fashion.
|
||||||
|
/// </para>
|
||||||
|
/// <br/><br/>
|
||||||
|
/// <para>
|
||||||
|
/// Note that this class makes some other bits of code pretty redundant e.g. <see cref="UrlHelperExtensions.GetUrlWithCacheBust"/> will
|
||||||
|
/// concatenate version with CacheBuster value and hash again, but there's no real harm so can think about that later.
|
||||||
|
/// </para>
|
||||||
|
/// </remarks>
|
||||||
|
internal class UmbracoSmidgeConfigCacheBuster : ICacheBuster
|
||||||
|
{
|
||||||
|
private readonly IOptions<RuntimeMinificationSettings> _runtimeMinificationSettings;
|
||||||
|
private readonly IUmbracoVersion _umbracoVersion;
|
||||||
|
private readonly IEntryAssemblyMetadata _entryAssemblyMetadata;
|
||||||
|
|
||||||
|
private string _cacheBusterValue;
|
||||||
|
|
||||||
|
public UmbracoSmidgeConfigCacheBuster(
|
||||||
|
IOptions<RuntimeMinificationSettings> runtimeMinificationSettings,
|
||||||
|
IUmbracoVersion umbracoVersion,
|
||||||
|
IEntryAssemblyMetadata entryAssemblyMetadata)
|
||||||
|
{
|
||||||
|
_runtimeMinificationSettings = runtimeMinificationSettings ?? throw new ArgumentNullException(nameof(runtimeMinificationSettings));
|
||||||
|
_umbracoVersion = umbracoVersion ?? throw new ArgumentNullException(nameof(umbracoVersion));
|
||||||
|
_entryAssemblyMetadata = entryAssemblyMetadata ?? throw new ArgumentNullException(nameof(entryAssemblyMetadata));
|
||||||
|
}
|
||||||
|
|
||||||
|
private string CacheBusterValue
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_cacheBusterValue != null)
|
||||||
|
{
|
||||||
|
return _cacheBusterValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assembly Name adds a bit of uniqueness across sites when version missing from config.
|
||||||
|
// Adds a bit of security through obscurity that was asked for in standup.
|
||||||
|
var prefix = _runtimeMinificationSettings.Value.Version ?? _entryAssemblyMetadata.Name ?? string.Empty;
|
||||||
|
var umbracoVersion = _umbracoVersion.SemanticVersion.ToString();
|
||||||
|
var downstreamVersion = _entryAssemblyMetadata.InformationalVersion;
|
||||||
|
|
||||||
|
_cacheBusterValue = $"{prefix}_{umbracoVersion}_{downstreamVersion}".GenerateHash();
|
||||||
|
|
||||||
|
return _cacheBusterValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetValue() => CacheBusterValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
5
tests/.editorconfig
Normal file
5
tests/.editorconfig
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
root = false
|
||||||
|
|
||||||
|
[*.cs]
|
||||||
|
csharp_style_var_when_type_is_apparent = true:none
|
||||||
|
csharp_style_var_elsewhere = true:none
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
using AutoFixture;
|
||||||
|
using AutoFixture.AutoMoq;
|
||||||
|
using AutoFixture.Kernel;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using Moq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using Smidge;
|
||||||
|
using Smidge.Cache;
|
||||||
|
using Umbraco.Cms.Core.Configuration;
|
||||||
|
using Umbraco.Cms.Core.Configuration.Models;
|
||||||
|
using Umbraco.Cms.Core.Semver;
|
||||||
|
using Umbraco.Cms.Web.Common.RuntimeMinification;
|
||||||
|
using Umbraco.Extensions;
|
||||||
|
|
||||||
|
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Web.Common.RuntimeMinification
|
||||||
|
{
|
||||||
|
/// <remarks>
|
||||||
|
/// UmbracoCustomizations kindly configures an IUmbracoVersion so we need to go verbose without AutoMoqData
|
||||||
|
/// </remarks>
|
||||||
|
[TestFixture]
|
||||||
|
public class UmbracoSmidgeConfigCacheBusterTests
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void GetValue_DefaultReleaseSetupWithNoConfiguredVersion_HasSensibleDefaults()
|
||||||
|
{
|
||||||
|
var fixture = new Fixture();
|
||||||
|
fixture.Customize(new AutoMoqCustomization());
|
||||||
|
|
||||||
|
var umbracoVersion = fixture.Freeze<Mock<IUmbracoVersion>>();
|
||||||
|
var entryAssemblyMetadata = fixture.Freeze<Mock<IEntryAssemblyMetadata>>();
|
||||||
|
var sut = fixture.Create<UmbracoSmidgeConfigCacheBuster>();
|
||||||
|
|
||||||
|
umbracoVersion.Setup(x => x.SemanticVersion).Returns(new SemVersion(9, 4, 5, "beta", "41658f99"));
|
||||||
|
entryAssemblyMetadata.Setup(x => x.Name).Returns("Bills.Brilliant.Bakery");
|
||||||
|
entryAssemblyMetadata.Setup(x => x.InformationalVersion).Returns("42.1.2-alpha+41658f99");
|
||||||
|
|
||||||
|
var result = sut.GetValue();
|
||||||
|
|
||||||
|
var expected = $"Bills.Brilliant.Bakery_9.4.5-beta+41658f99_42.1.2-alpha+41658f99".GenerateHash();
|
||||||
|
Assert.AreEqual(expected, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void GetValue_DefaultReleaseSetupWithConfiguredVersion_HasSensibleDefaults()
|
||||||
|
{
|
||||||
|
var config = Options.Create(new RuntimeMinificationSettings { Version = "1" });
|
||||||
|
var fixture = new Fixture();
|
||||||
|
fixture.Customize(new AutoMoqCustomization());
|
||||||
|
fixture.Inject(config);
|
||||||
|
|
||||||
|
var umbracoVersion = fixture.Freeze<Mock<IUmbracoVersion>>();
|
||||||
|
var entryAssemblyMetadata = fixture.Freeze<Mock<IEntryAssemblyMetadata>>();
|
||||||
|
var sut = fixture.Create<UmbracoSmidgeConfigCacheBuster>();
|
||||||
|
|
||||||
|
umbracoVersion.Setup(x => x.SemanticVersion).Returns(new SemVersion(9, 4, 5, "beta", "41658f99"));
|
||||||
|
entryAssemblyMetadata.Setup(x => x.Name).Returns("Bills.Brilliant.Bakery");
|
||||||
|
entryAssemblyMetadata.Setup(x => x.InformationalVersion).Returns("42.1.2-alpha+41658f99");
|
||||||
|
|
||||||
|
var result = sut.GetValue();
|
||||||
|
|
||||||
|
var expected = $"1_9.4.5-beta+41658f99_42.1.2-alpha+41658f99".GenerateHash();
|
||||||
|
Assert.AreEqual(expected, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void GetValue_DefaultReleaseSetupWithNoConfiguredVersion_ChangesWhenUmbracoVersionChanges()
|
||||||
|
{
|
||||||
|
var fixture = new Fixture();
|
||||||
|
fixture.Customize(new AutoMoqCustomization());
|
||||||
|
|
||||||
|
var umbracoVersion = fixture.Freeze<Mock<IUmbracoVersion>>();
|
||||||
|
var entryAssemblyMetadata = fixture.Freeze<Mock<IEntryAssemblyMetadata>>();
|
||||||
|
var sut = fixture.Create<UmbracoSmidgeConfigCacheBuster>();
|
||||||
|
|
||||||
|
umbracoVersion.Setup(x => x.SemanticVersion).Returns(new SemVersion(9, 4, 5, "beta", "41658f99"));
|
||||||
|
entryAssemblyMetadata.Setup(x => x.Name).Returns("Bills.Brilliant.Bakery");
|
||||||
|
entryAssemblyMetadata.Setup(x => x.InformationalVersion).Returns("42.1.2-alpha+41658f99");
|
||||||
|
|
||||||
|
var before = sut.GetValue();
|
||||||
|
|
||||||
|
umbracoVersion.Setup(x => x.SemanticVersion).Returns(new SemVersion(9, 5, 0, "beta", "41658f99"));
|
||||||
|
sut = fixture.Create<UmbracoSmidgeConfigCacheBuster>();
|
||||||
|
|
||||||
|
var after = sut.GetValue();
|
||||||
|
|
||||||
|
Assert.AreNotEqual(before, after);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void GetValue_DefaultReleaseSetupWithNoConfiguredVersion_ChangesWhenDownstreamVersionChanges()
|
||||||
|
{
|
||||||
|
var fixture = new Fixture();
|
||||||
|
fixture.Customize(new AutoMoqCustomization());
|
||||||
|
|
||||||
|
var umbracoVersion = fixture.Freeze<Mock<IUmbracoVersion>>();
|
||||||
|
var entryAssemblyMetadata = fixture.Freeze<Mock<IEntryAssemblyMetadata>>();
|
||||||
|
var sut = fixture.Create<UmbracoSmidgeConfigCacheBuster>();
|
||||||
|
|
||||||
|
umbracoVersion.Setup(x => x.SemanticVersion).Returns(new SemVersion(9, 4, 5, "beta", "41658f99"));
|
||||||
|
entryAssemblyMetadata.Setup(x => x.Name).Returns("Bills.Brilliant.Bakery");
|
||||||
|
entryAssemblyMetadata.Setup(x => x.InformationalVersion).Returns("42.1.2-alpha+41658f99");
|
||||||
|
|
||||||
|
var before = sut.GetValue();
|
||||||
|
|
||||||
|
entryAssemblyMetadata.Setup(x => x.InformationalVersion).Returns("42.2.0-rc");
|
||||||
|
sut = fixture.Create<UmbracoSmidgeConfigCacheBuster>();
|
||||||
|
|
||||||
|
var after = sut.GetValue();
|
||||||
|
|
||||||
|
Assert.AreNotEqual(before, after);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
<s:String x:Key="/Default/PatternsAndTemplates/StructuralSearch/Pattern/=2DA32DA040A7D74599ABE288C7224CF0/Severity/@EntryValue">HINT</s:String>
|
<s:String x:Key="/Default/PatternsAndTemplates/StructuralSearch/Pattern/=2DA32DA040A7D74599ABE288C7224CF0/Severity/@EntryValue">HINT</s:String>
|
||||||
<s:Boolean x:Key="/Default/PatternsAndTemplates/StructuralSearch/Pattern/=37A0B37A0ABAA34AA5CB32A93653C4FE/@KeyIndexDefined">False</s:Boolean>
|
<s:Boolean x:Key="/Default/PatternsAndTemplates/StructuralSearch/Pattern/=37A0B37A0ABAA34AA5CB32A93653C4FE/@KeyIndexDefined">False</s:Boolean>
|
||||||
<s:String x:Key="/Default/CodeInspection/CSharpLanguageProject/LanguageLevel/@EntryValue">Default</s:String>
|
<s:String x:Key="/Default/CodeInspection/CSharpLanguageProject/LanguageLevel/@EntryValue">Default</s:String>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Smidge/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Umbraco/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Umbraco/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=unpublish/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=unpublish/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=unpublishing/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=unpublishing/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
||||||
Reference in New Issue
Block a user