Files
Umbraco-CMS/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/ScriptRepositoryTest.cs

358 lines
12 KiB
C#
Raw Normal View History

// Copyright (c) Umbraco.
// See LICENSE for more details.
using System.IO;
2018-06-29 19:52:40 +02:00
using System.Linq;
using System.Text;
2020-09-17 11:35:29 +02:00
using Microsoft.Extensions.Logging;
Netcore: File systems rework (#10181) * Allow IMediaFileSystem to be replace in the DI, or registered with inner filesystem * Remove GetFileSystem from Filesystems It was only used by tests. * Make MediaFileSystem inherit from PhysicalFileSystem directly * Remove FileSystemWrapper * Remove inner filesystem from MediaFileSystem * Add MediaFileManager and bare minimum to make it testable * Remove MediaFileSystem * Fix unit tests using MediaFileManager * Remove IFileSystem and rely only on FileSystem * Hide dangerous methods in FileSystems and do some cleaning * Apply stylecop warnings to MediaFileManager * Add FilesystemsCreator to Tests.Common This allows you to create an instance if FileSystems with your own specified IFileSystem for testing purposes outside our own test suite. * Allow the stylesheet filesystem to be replaced. * Fix tests * Don't save stylesheetWrapper in a temporary var * refactor(FileSystems): change how stylesheet filesystem is registered * fix(FileSystems): unable to overwrite media filesystem SetMediaFileSystem added the MediaManager as a Singleton instead of replacing the existing instance. * fix(FileSystems): calling AddFileSystems replaces MediaManager When calling AddFileSystems after SetMediaFileSystem the MediaManager gets replaced by the default PhysicalFileSystem, so instead of calling SetMediaFileSystem in AddFileSystems we now call TrySetMediaFileSystem instead. This method will not replace any existing instance of the MediaManager if there's already a MediaManager registered. * Use SetMediaFileSystem instead of TrySet, and rename AddFilesystems to ConfigureFileSystems Also don't call AddFileSystems again in ConfigureFilesystems * Don't wrap CSS filesystem twice * Add CreateShadowWrapperInternal to avoid casting * Throw UnauthorizedAccessException isntead of InvalidOperationException * Remove ResetShadowId Co-authored-by: Rasmus John Pedersen <mail@rjp.dk>
2021-04-27 09:52:17 +02:00
using Microsoft.Extensions.Options;
2018-06-29 19:52:40 +02:00
using NUnit.Framework;
using Umbraco.Cms.Core.Configuration.Models;
using Umbraco.Cms.Core.Hosting;
using Umbraco.Cms.Core.IO;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Persistence.Repositories;
using Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement;
Netcore: File systems rework (#10181) * Allow IMediaFileSystem to be replace in the DI, or registered with inner filesystem * Remove GetFileSystem from Filesystems It was only used by tests. * Make MediaFileSystem inherit from PhysicalFileSystem directly * Remove FileSystemWrapper * Remove inner filesystem from MediaFileSystem * Add MediaFileManager and bare minimum to make it testable * Remove MediaFileSystem * Fix unit tests using MediaFileManager * Remove IFileSystem and rely only on FileSystem * Hide dangerous methods in FileSystems and do some cleaning * Apply stylecop warnings to MediaFileManager * Add FilesystemsCreator to Tests.Common This allows you to create an instance if FileSystems with your own specified IFileSystem for testing purposes outside our own test suite. * Allow the stylesheet filesystem to be replaced. * Fix tests * Don't save stylesheetWrapper in a temporary var * refactor(FileSystems): change how stylesheet filesystem is registered * fix(FileSystems): unable to overwrite media filesystem SetMediaFileSystem added the MediaManager as a Singleton instead of replacing the existing instance. * fix(FileSystems): calling AddFileSystems replaces MediaManager When calling AddFileSystems after SetMediaFileSystem the MediaManager gets replaced by the default PhysicalFileSystem, so instead of calling SetMediaFileSystem in AddFileSystems we now call TrySetMediaFileSystem instead. This method will not replace any existing instance of the MediaManager if there's already a MediaManager registered. * Use SetMediaFileSystem instead of TrySet, and rename AddFilesystems to ConfigureFileSystems Also don't call AddFileSystems again in ConfigureFilesystems * Don't wrap CSS filesystem twice * Add CreateShadowWrapperInternal to avoid casting * Throw UnauthorizedAccessException isntead of InvalidOperationException * Remove ResetShadowId Co-authored-by: Rasmus John Pedersen <mail@rjp.dk>
2021-04-27 09:52:17 +02:00
using Umbraco.Cms.Tests.Common.TestHelpers;
using Umbraco.Cms.Tests.Common.Testing;
using Umbraco.Cms.Tests.Integration.Testing;
2018-06-29 19:52:40 +02:00
namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Persistence.Repositories;
[TestFixture]
[UmbracoTest(Database = UmbracoTestOptions.Database.None)]
Remove the non-controversial, straightforward obsoleted constructs for Umbraco 16 (#18661) * Removed obsoletes from IConfigManipulator. * Removed obsolete models builder extensions. * Removed the obsolete ContentDashboardSettings. * Removed the obsolete InstallMissingDatabase setting on GlobalSettings. * Removed obsolete NuCache settings. * Removed obsolete RuntimeMinificationSettings. * Removed obsolete health check constant. * Removed obsolete icon constant. * Removed obsolete telemetry constant. * Removed obsolete property and constructor on UmbracoBuilder. * Removed obsolete constructor on AuditNotificationsHandler. * Removed obsolete constructor on HTTP header health checks. * Removed obsolete constructor on MediaFileManager. * Removed obsolete GetDefaultFileContent on ViewHelper. * Remove obsoleted methods on embed providers. * Fix tests. * Removed obsolete constructors on BlockEditorDataConverter. * Removed obsolete SeedCacheDuration property on CacheSettings. * Removed obsolete PublishCulture on ContentRepositoryExtensions. * Removed obsolete MonitorLock. * Removed obsolete synchronous HasSavedValues from IDataTypeUsageService and IDataTypeUsageRepository. * Removed obsolete HasSavedPropertyValues from IPropertyTypeUsageService and IPropertyTypeUsageRepository. * Removed obsolete methods in ITrackedReferencesService and ITrackedReferencesRepository. * Removed obsolete DateValueEditor constructors. * Removed obsolete GetAutomaticRelationTypesAliases. * Removed obsolete constructor on TextOnlyValueEditor. * Removed obsolete constructors on RegexValidator and RequiredValidator. * Removed obsolete constructs on SliderValueConverter and TagsValueConverter. * Removed obsolete GetContentType methods from IPublishedCache. * Removed ContentFinderByIdPath. * Removed obsolete constructor on DefaultMediaUrlProvider. * Removed obsolete constructor on Domain. * Removed obsolete constructor on PublishedRequest. * Removed obsolete methods on CheckPermissions. * Removed obsolete GetUserId from IBackOfficeSecurity. * Removed obsolete methods on LegacyPasswordSecurity. * Removed obsolete constructors on AuditService. * Removed obsolete methods on IContentEditingService. * Remove obsolete constructors and methods on ContentService/IContentService. * Removed obsolete constructor in ContentTypeEditingService. * Removed obsolete constructor in MediaTypeEditingService. * Removed obsolete constructor in MemberTypeEditingService. * Removed obsolete constructor in ContentTypeService. * Removed obsolete constructors in ContentTypeServiceBase. * Removed obsolete constructors and methods in ContentVersionService. * Removed obsolete constructor in DataTypeUsageService. * Removed obsolete constructor in DomainService. * Removed obsolete constructor in FileService. * Removes obsolete AttemptMove from IContentService. * Removes obsolete SetPreventCleanup from IContentVersionService. * Removes obsolete GetReferences from IDataTypeService. * Removed obsolete SetConsentLevel from IMetricsConsentService. * Removed obsolete methods from IPackageDataInstallation. * Removed obsolete methods from IPackagingService. * Removed obsolete methods on ITwoFactorLoginService. Removed obsolete ITemporaryMediaService. * Removed obsolete constructor from MediaService, MemberTypeService and MediaTypeService. * More obsolete constructors. * Removed obsoleted overloads on IPropertyValidationService. * Fixed build for tests. * Removed obsolete constructor for PublicAccessService, UserService and RelationService. * Removed GetDefaultMemberType. * Removed obsolete user group functionality from IUserService. * Removed obsolete extension methods on IUserService. * Removed obsolete method from ITelemetryService. * Removed obsolete UdiParserServiceConnectors. * Removed obsolete method on ICookieManager. * Removed obsolete DynamicContext. * Removed obsolete XmlHelper. * Fixed failing integration tests. * Removed obsoletes in Umbraco.Cms.Api.Common * Removed obsoletes in Umbraco.Cms.Api.Delivery * Removed obsoletes in Umbraco.Cms.Api.Management * Removed obsoletes in Umbraco.Examine.Lucene * Removed obsoletes in Umbraco.Infrastructure * Fix failing delivery API contract integration test. * Made integration tests internal. * Removed obsoletes from web projects. * Fix build. * Removed Twitter OEmbed provider * Removed obsolete constructor on PublishedDataType. * Removed obsolete constructors on PublishedCacheBase. * Removed the obsolete PropertyEditorTagsExtensions. * Removed obsoletion properties on configuration response models (#18697) * Removed obsolete methods from server-side models. * Update client-side types and sdk. * Update client-side files. * Removed obsoletion of Utf8ToAsciiConverter.ToAsciiString overload. (#18694) * Removed obsolete method in UserService. (#18710) * Removed obsoleted group alias keys from being publicly available. (#18682) * Removed unneceessary ApiVersion attribute. * Clean-up obsoletions on MemberService (#18703) * Removed obsoleted method on MemberService, added future obsoletion to interface and updated all callers. * Removed obsoletion on member service method that's not obsolete on the interface.
2025-03-21 18:02:31 +01:00
internal sealed class ScriptRepositoryTest : UmbracoIntegrationTest
2018-06-29 19:52:40 +02:00
{
[SetUp]
public void SetUpFileSystem()
2018-06-29 19:52:40 +02:00
{
var path = GlobalSettings.UmbracoScriptsPath;
_fileSystem = new PhysicalFileSystem(IOHelper, HostingEnvironment, LoggerFactory.CreateLogger<PhysicalFileSystem>(), HostingEnvironment.MapPathWebRoot(path), HostingEnvironment.ToAbsolute(path));
_fileSystems = FileSystemsCreator.CreateTestFileSystems(
LoggerFactory,
IOHelper,
GetRequiredService<IOptions<GlobalSettings>>(),
HostingEnvironment,
null,
null,
_fileSystem,
null);
using (var stream = CreateStream("Umbraco.Sys.registerNamespace(\"Umbraco.Utils\");"))
2018-06-29 19:52:40 +02:00
{
_fileSystem.AddFile("test-script.js", stream);
2018-06-29 19:52:40 +02:00
}
}
2018-06-29 19:52:40 +02:00
[TearDown]
public void TearDownFileSystem()
{
// Delete all files
Purge(_fileSystems.ScriptsFileSystem, string.Empty);
_fileSystems = null;
}
private IHostingEnvironment HostingEnvironment => GetRequiredService<IHostingEnvironment>();
private FileSystems _fileSystems;
private IFileSystem _fileSystem;
private IScriptRepository CreateRepository()
{
var globalSettings = new GlobalSettings();
return new ScriptRepository(_fileSystems);
}
2018-06-29 19:52:40 +02:00
[Test]
public void Can_Instantiate_Repository()
{
// Arrange
var provider = ScopeProvider;
using (var scope = ScopeProvider.CreateScope())
2018-06-29 19:52:40 +02:00
{
// Act
var repository = CreateRepository();
// Assert
Assert.That(repository, Is.Not.Null);
2018-06-29 19:52:40 +02:00
}
}
2018-06-29 19:52:40 +02:00
[Test]
public void Can_Perform_Add_On_ScriptRepository()
{
// Arrange
var provider = ScopeProvider;
using (var scope = ScopeProvider.CreateScope())
2018-06-29 19:52:40 +02:00
{
var repository = CreateRepository();
// Act
var script = new Script("test-add-script.js") { Content = "/// <reference name=\"MicrosoftAjax.js\"/>" };
repository.Save(script);
// Assert
Assert.That(_fileSystem.FileExists("test-add-script.js"), Is.True);
2018-06-29 19:52:40 +02:00
}
}
2018-06-29 19:52:40 +02:00
[Test]
public void Can_Perform_Update_On_ScriptRepository()
{
// Arrange
var provider = ScopeProvider;
using (var scope = ScopeProvider.CreateScope())
2018-06-29 19:52:40 +02:00
{
var repository = CreateRepository();
2018-06-29 19:52:40 +02:00
// Act
var script = new Script("test-updated-script.js") { Content = "/// <reference name=\"MicrosoftAjax.js\"/>" };
repository.Save(script);
script.Content = "/// <reference name=\"MicrosoftAjax-Updated.js\"/>";
repository.Save(script);
var scriptUpdated = repository.Get("test-updated-script.js");
2018-06-29 19:52:40 +02:00
// Assert
Assert.That(_fileSystem.FileExists("test-updated-script.js"), Is.True);
Assert.That(scriptUpdated.Content, Is.EqualTo("/// <reference name=\"MicrosoftAjax-Updated.js\"/>"));
2018-06-29 19:52:40 +02:00
}
}
2018-06-29 19:52:40 +02:00
[Test]
public void Can_Perform_Delete_On_ScriptRepository()
{
// Arrange
using (var scope = ScopeProvider.CreateScope())
2018-06-29 19:52:40 +02:00
{
var repository = CreateRepository();
// Act
var script = repository.Get("test-script.js");
repository.Delete(script);
// Assert
Assert.IsFalse(repository.Exists("test-script.js"));
2018-06-29 19:52:40 +02:00
}
}
2018-06-29 19:52:40 +02:00
[Test]
public void Can_Perform_Get_On_ScriptRepository()
{
// Arrange
using (var scope = ScopeProvider.CreateScope())
2018-06-29 19:52:40 +02:00
{
var repository = CreateRepository();
// Act
var exists = repository.Get("test-script.js");
// Assert
Assert.That(exists, Is.Not.Null);
Assert.That(exists.Alias, Is.EqualTo("test-script"));
Assert.That(exists.Name, Is.EqualTo("test-script.js"));
2018-06-29 19:52:40 +02:00
}
}
2018-06-29 19:52:40 +02:00
[Test]
public void Can_Perform_GetAll_On_ScriptRepository()
{
// Arrange
using (var scope = ScopeProvider.CreateScope())
2018-06-29 19:52:40 +02:00
{
var repository = CreateRepository();
var script = new Script("test-script1.js") { Content = "/// <reference name=\"MicrosoftAjax.js\"/>" };
repository.Save(script);
var script2 = new Script("test-script2.js") { Content = "/// <reference name=\"MicrosoftAjax.js\"/>" };
repository.Save(script2);
var script3 = new Script("test-script3.js") { Content = "/// <reference name=\"MicrosoftAjax.js\"/>" };
repository.Save(script3);
// Act
var scripts = repository.GetMany().ToArray();
// Assert
Assert.That(scripts, Is.Not.Null);
Assert.That(scripts.Any(), Is.True);
Assert.That(scripts.Any(x => x == null), Is.False);
Assert.That(scripts.Count(), Is.EqualTo(4));
2018-06-29 19:52:40 +02:00
}
}
2018-06-29 19:52:40 +02:00
[Test]
public void Can_Perform_GetAll_With_Params_On_ScriptRepository()
{
// Arrange
using (var scope = ScopeProvider.CreateScope())
2018-06-29 19:52:40 +02:00
{
var repository = CreateRepository();
var script = new Script("test-script1.js") { Content = "/// <reference name=\"MicrosoftAjax.js\"/>" };
repository.Save(script);
var script2 = new Script("test-script2.js") { Content = "/// <reference name=\"MicrosoftAjax.js\"/>" };
repository.Save(script2);
var script3 = new Script("test-script3.js") { Content = "/// <reference name=\"MicrosoftAjax.js\"/>" };
repository.Save(script3);
// Act
var scripts = repository.GetMany("test-script1.js", "test-script2.js").ToArray();
// Assert
Assert.That(scripts, Is.Not.Null);
Assert.That(scripts.Any(), Is.True);
Assert.That(scripts.Any(x => x == null), Is.False);
Assert.That(scripts.Count(), Is.EqualTo(2));
2018-06-29 19:52:40 +02:00
}
}
2018-06-29 19:52:40 +02:00
[Test]
public void Can_Perform_Exists_On_ScriptRepository()
{
// Arrange
using (var scope = ScopeProvider.CreateScope())
2018-06-29 19:52:40 +02:00
{
var repository = CreateRepository();
2018-06-29 19:52:40 +02:00
// Act
var exists = repository.Exists("test-script.js");
2018-06-29 19:52:40 +02:00
// Assert
Assert.That(exists, Is.True);
2018-06-29 19:52:40 +02:00
}
}
2018-06-29 19:52:40 +02:00
[Test]
public void Can_Perform_Move_On_ScriptRepository()
{
const string content = "/// <reference name=\"MicrosoftAjax.js\"/>";
2018-06-29 19:52:40 +02:00
// Arrange
using (var scope = ScopeProvider.CreateScope())
{
var repository = CreateRepository();
2018-06-29 19:52:40 +02:00
IScript script = new Script("test-move-script.js") { Content = content };
repository.Save(script);
// Act
script = repository.Get("test-move-script.js");
script.Path = "moved/test-move-script.js";
repository.Save(script);
var existsOld = repository.Exists("test-move-script.js");
var existsNew = repository.Exists("moved/test-move-script.js");
2018-06-29 19:52:40 +02:00
script = repository.Get("moved/test-move-script.js");
2018-06-29 19:52:40 +02:00
// Assert
Assert.IsNotNull(script);
Assert.IsFalse(existsOld);
Assert.IsTrue(existsNew);
Assert.AreEqual(content, script.Content);
2018-06-29 19:52:40 +02:00
}
}
2018-06-29 19:52:40 +02:00
[Test]
public void PathTests()
{
// unless noted otherwise, no changes / 7.2.8
using (var scope = ScopeProvider.CreateScope())
2018-06-29 19:52:40 +02:00
{
var repository = CreateRepository();
2018-06-29 19:52:40 +02:00
IScript script = new Script("test-path-1.js") { Content = "// script" };
repository.Save(script);
Assert.IsTrue(_fileSystem.FileExists("test-path-1.js"));
Assert.AreEqual("test-path-1.js", script.Path);
Assert.AreEqual("/scripts/test-path-1.js", script.VirtualPath);
2018-06-29 19:52:40 +02:00
// ensure you can prefix the same path as the root path name
script = new Script("scripts/path-2/test-path-2.js") { Content = "// script" };
repository.Save(script);
Assert.IsTrue(_fileSystem.FileExists("scripts/path-2/test-path-2.js"));
Assert.AreEqual("scripts\\path-2\\test-path-2.js".Replace("\\", $"{Path.DirectorySeparatorChar}"), script.Path);
Assert.AreEqual("/scripts/scripts/path-2/test-path-2.js", script.VirtualPath);
2018-06-29 19:52:40 +02:00
script = new Script("path-2/test-path-2.js") { Content = "// script" };
repository.Save(script);
Assert.IsTrue(_fileSystem.FileExists("path-2/test-path-2.js"));
Assert.AreEqual("path-2\\test-path-2.js".Replace("\\", $"{Path.DirectorySeparatorChar}"), script.Path); // fixed in 7.3 - 7.2.8 does not update the path
Assert.AreEqual("/scripts/path-2/test-path-2.js", script.VirtualPath);
2018-06-29 19:52:40 +02:00
script = repository.Get("path-2/test-path-2.js");
Assert.IsNotNull(script);
Assert.AreEqual("path-2\\test-path-2.js".Replace("\\", $"{Path.DirectorySeparatorChar}"), script.Path);
Assert.AreEqual("/scripts/path-2/test-path-2.js", script.VirtualPath);
2018-06-29 19:52:40 +02:00
script = new Script("path-2\\test-path-3.js") { Content = "// script" };
repository.Save(script);
Assert.IsTrue(_fileSystem.FileExists("path-2/test-path-3.js"));
Assert.AreEqual("path-2\\test-path-3.js".Replace("\\", $"{Path.DirectorySeparatorChar}"), script.Path);
Assert.AreEqual("/scripts/path-2/test-path-3.js", script.VirtualPath);
2018-06-29 19:52:40 +02:00
script = repository.Get("path-2/test-path-3.js");
Assert.IsNotNull(script);
Assert.AreEqual("path-2\\test-path-3.js".Replace("\\", $"{Path.DirectorySeparatorChar}"), script.Path);
Assert.AreEqual("/scripts/path-2/test-path-3.js", script.VirtualPath);
2018-06-29 19:52:40 +02:00
script = repository.Get("path-2\\test-path-3.js");
Assert.IsNotNull(script);
Assert.AreEqual("path-2\\test-path-3.js".Replace("\\", $"{Path.DirectorySeparatorChar}"), script.Path);
Assert.AreEqual("/scripts/path-2/test-path-3.js", script.VirtualPath);
2018-06-29 19:52:40 +02:00
script = new Script("..\\test-path-4.js") { Content = "// script" };
Assert.Throws<UnauthorizedAccessException>(() =>
repository.Save(script));
2018-06-29 19:52:40 +02:00
script = new Script("\\test-path-5.js") { Content = "// script" };
repository.Save(script);
script = repository.Get("\\test-path-5.js");
Assert.IsNotNull(script);
Assert.AreEqual("test-path-5.js", script.Path);
Assert.AreEqual("/scripts/test-path-5.js", script.VirtualPath);
script = repository.Get("missing.js");
Assert.IsNull(script);
2018-06-29 19:52:40 +02:00
Assert.Throws<UnauthorizedAccessException>(() => script = repository.Get("..\\test-path-4.js"));
Assert.Throws<UnauthorizedAccessException>(() => script = repository.Get("../packages.config"));
2018-06-29 19:52:40 +02:00
}
}
2018-06-29 19:52:40 +02:00
private void Purge(IFileSystem fs, string path)
{
var files = fs.GetFiles(path, "*.js");
foreach (var file in files)
2018-06-29 19:52:40 +02:00
{
fs.DeleteFile(file);
2018-06-29 19:52:40 +02:00
}
var dirs = fs.GetDirectories(path);
foreach (var dir in dirs)
2018-06-29 19:52:40 +02:00
{
Purge(fs, dir);
fs.DeleteDirectory(dir);
}
}
2018-06-29 19:52:40 +02:00
protected Stream CreateStream(string contents = null)
{
if (string.IsNullOrEmpty(contents))
{
contents = "/* test */";
2018-06-29 19:52:40 +02:00
}
var bytes = Encoding.UTF8.GetBytes(contents);
var stream = new MemoryStream(bytes);
return stream;
2018-06-29 19:52:40 +02:00
}
}