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

349 lines
13 KiB
C#
Raw Normal View History

// Copyright (c) Umbraco.
// See LICENSE for more details.
using System;
using System.Collections.Generic;
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.Core.Scoping;
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
2018-06-29 19:52:40 +02:00
{
[TestFixture]
[UmbracoTest(Database = UmbracoTestOptions.Database.None)]
public class ScriptRepositoryTest : UmbracoIntegrationTest
2018-06-29 19:52:40 +02:00
{
private IHostingEnvironment HostingEnvironment => GetRequiredService<IHostingEnvironment>();
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
private FileSystems _fileSystems;
2018-06-29 19:52:40 +02:00
private IFileSystem _fileSystem;
[SetUp]
public void SetUpFileSystem()
2018-06-29 19:52:40 +02:00
{
string path = GlobalSettings.UmbracoScriptsPath;
_fileSystem = new PhysicalFileSystem(IOHelper, HostingEnvironment, LoggerFactory.CreateLogger<PhysicalFileSystem>(), HostingEnvironment.MapPathWebRoot(path), HostingEnvironment.ToAbsolute(path));
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
_fileSystems = FileSystemsCreator.CreateTestFileSystems(LoggerFactory, IOHelper, GetRequiredService<IOptions<GlobalSettings>>(),
HostingEnvironment,
null, null, null, _fileSystem, null);
using (Stream stream = CreateStream("Umbraco.Sys.registerNamespace(\"Umbraco.Utils\");"))
2018-06-29 19:52:40 +02:00
{
_fileSystem.AddFile("test-script.js", stream);
}
}
[TearDown]
public void TearDownFileSystem()
{
// Delete all files
Purge(_fileSystems.ScriptsFileSystem, string.Empty);
_fileSystems = null;
}
private IScriptRepository CreateRepository()
2018-06-29 19:52:40 +02:00
{
var globalSettings = new GlobalSettings();
return new ScriptRepository(_fileSystems, IOHelper, Microsoft.Extensions.Options.Options.Create(globalSettings));
2018-06-29 19:52:40 +02:00
}
[Test]
public void Can_Instantiate_Repository()
{
// Arrange
IScopeProvider provider = ScopeProvider;
using (IScope scope = ScopeProvider.CreateScope())
2018-06-29 19:52:40 +02:00
{
// Act
IScriptRepository repository = CreateRepository();
2018-06-29 19:52:40 +02:00
// Assert
Assert.That(repository, Is.Not.Null);
}
}
[Test]
public void Can_Perform_Add_On_ScriptRepository()
{
// Arrange
IScopeProvider provider = ScopeProvider;
using (IScope scope = ScopeProvider.CreateScope())
2018-06-29 19:52:40 +02:00
{
IScriptRepository repository = CreateRepository();
2018-06-29 19:52:40 +02:00
// Act
var script = new Script("test-add-script.js") { Content = "/// <reference name=\"MicrosoftAjax.js\"/>" };
repository.Save(script);
// Assert
2018-06-29 19:52:40 +02:00
Assert.That(_fileSystem.FileExists("test-add-script.js"), Is.True);
}
}
[Test]
public void Can_Perform_Update_On_ScriptRepository()
{
// Arrange
IScopeProvider provider = ScopeProvider;
using (IScope scope = ScopeProvider.CreateScope())
2018-06-29 19:52:40 +02:00
{
IScriptRepository 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);
2018-06-29 19:52:40 +02:00
script.Content = "/// <reference name=\"MicrosoftAjax-Updated.js\"/>";
repository.Save(script);
IScript 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\"/>"));
}
}
[Test]
public void Can_Perform_Delete_On_ScriptRepository()
{
// Arrange
using (IScope scope = ScopeProvider.CreateScope())
2018-06-29 19:52:40 +02:00
{
IScriptRepository repository = CreateRepository();
2018-06-29 19:52:40 +02:00
// Act
IScript script = repository.Get("test-script.js");
2018-06-29 19:52:40 +02:00
repository.Delete(script);
2018-06-29 19:52:40 +02:00
// Assert
Assert.IsFalse(repository.Exists("test-script.js"));
}
}
[Test]
public void Can_Perform_Get_On_ScriptRepository()
{
// Arrange
using (IScope scope = ScopeProvider.CreateScope())
2018-06-29 19:52:40 +02:00
{
IScriptRepository repository = CreateRepository();
2018-06-29 19:52:40 +02:00
// Act
IScript exists = repository.Get("test-script.js");
2018-06-29 19:52:40 +02:00
// Assert
Assert.That(exists, Is.Not.Null);
Assert.That(exists.Alias, Is.EqualTo("test-script"));
Assert.That(exists.Name, Is.EqualTo("test-script.js"));
}
}
[Test]
public void Can_Perform_GetAll_On_ScriptRepository()
{
// Arrange
using (IScope scope = ScopeProvider.CreateScope())
2018-06-29 19:52:40 +02:00
{
IScriptRepository repository = CreateRepository();
2018-06-29 19:52:40 +02:00
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);
2018-06-29 19:52:40 +02:00
// Act
IEnumerable<IScript> scripts = repository.GetMany();
2018-06-29 19:52:40 +02:00
// 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));
}
}
[Test]
public void Can_Perform_GetAll_With_Params_On_ScriptRepository()
{
// Arrange
using (IScope scope = ScopeProvider.CreateScope())
2018-06-29 19:52:40 +02:00
{
IScriptRepository repository = CreateRepository();
2018-06-29 19:52:40 +02:00
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);
2018-06-29 19:52:40 +02:00
// Act
IEnumerable<IScript> scripts = repository.GetMany("test-script1.js", "test-script2.js");
2018-06-29 19:52:40 +02:00
// 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));
}
}
[Test]
public void Can_Perform_Exists_On_ScriptRepository()
{
// Arrange
using (IScope scope = ScopeProvider.CreateScope())
2018-06-29 19:52:40 +02:00
{
IScriptRepository repository = CreateRepository();
2018-06-29 19:52:40 +02:00
// Act
bool exists = repository.Exists("test-script.js");
2018-06-29 19:52:40 +02:00
// Assert
Assert.That(exists, Is.True);
}
}
[Test]
public void Can_Perform_Move_On_ScriptRepository()
{
const string content = "/// <reference name=\"MicrosoftAjax.js\"/>";
// Arrange
using (IScope scope = ScopeProvider.CreateScope())
2018-06-29 19:52:40 +02:00
{
IScriptRepository repository = CreateRepository();
2018-06-29 19:52:40 +02:00
IScript script = new Script("test-move-script.js") { Content = content };
2018-06-29 19:52:40 +02:00
repository.Save(script);
2018-06-29 19:52:40 +02:00
// Act
script = repository.Get("test-move-script.js");
script.Path = "moved/test-move-script.js";
repository.Save(script);
bool existsOld = repository.Exists("test-move-script.js");
bool existsNew = repository.Exists("moved/test-move-script.js");
2018-06-29 19:52:40 +02:00
script = repository.Get("moved/test-move-script.js");
// Assert
Assert.IsNotNull(script);
Assert.IsFalse(existsOld);
Assert.IsTrue(existsNew);
Assert.AreEqual(content, script.Content);
}
}
[Test]
public void PathTests()
{
// unless noted otherwise, no changes / 7.2.8
using (IScope scope = ScopeProvider.CreateScope())
2018-06-29 19:52:40 +02:00
{
IScriptRepository repository = CreateRepository();
2018-06-29 19:52:40 +02:00
IScript script = new Script("test-path-1.js") { Content = "// script" };
2018-06-29 19:52:40 +02:00
repository.Save(script);
2018-06-29 19:52:40 +02:00
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);
// ensure you can prefix the same path as the root path name
2018-06-29 19:52:40 +02:00
script = new Script("scripts/path-2/test-path-2.js") { Content = "// script" };
repository.Save(script);
2018-06-29 19:52:40 +02:00
Assert.IsTrue(_fileSystem.FileExists("scripts/path-2/test-path-2.js"));
2020-12-11 16:44:27 +00:00
Assert.AreEqual("scripts\\path-2\\test-path-2.js".Replace("\\", $"{Path.DirectorySeparatorChar}"), script.Path);
2018-06-29 19:52:40 +02:00
Assert.AreEqual("/scripts/scripts/path-2/test-path-2.js", script.VirtualPath);
script = new Script("path-2/test-path-2.js") { Content = "// script" };
repository.Save(script);
2018-06-29 19:52:40 +02:00
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
2018-06-29 19:52:40 +02:00
Assert.AreEqual("/scripts/path-2/test-path-2.js", script.VirtualPath);
script = repository.Get("path-2/test-path-2.js");
Assert.IsNotNull(script);
2020-12-11 16:44:27 +00:00
Assert.AreEqual("path-2\\test-path-2.js".Replace("\\", $"{Path.DirectorySeparatorChar}"), script.Path);
2018-06-29 19:52:40 +02:00
Assert.AreEqual("/scripts/path-2/test-path-2.js", script.VirtualPath);
script = new Script("path-2\\test-path-3.js") { Content = "// script" };
repository.Save(script);
2018-06-29 19:52:40 +02:00
Assert.IsTrue(_fileSystem.FileExists("path-2/test-path-3.js"));
2020-12-11 16:44:27 +00:00
Assert.AreEqual("path-2\\test-path-3.js".Replace("\\", $"{Path.DirectorySeparatorChar}"), script.Path);
2018-06-29 19:52:40 +02:00
Assert.AreEqual("/scripts/path-2/test-path-3.js", script.VirtualPath);
script = repository.Get("path-2/test-path-3.js");
Assert.IsNotNull(script);
2020-12-11 16:44:27 +00:00
Assert.AreEqual("path-2\\test-path-3.js".Replace("\\", $"{Path.DirectorySeparatorChar}"), script.Path);
2018-06-29 19:52:40 +02:00
Assert.AreEqual("/scripts/path-2/test-path-3.js", script.VirtualPath);
script = repository.Get("path-2\\test-path-3.js");
Assert.IsNotNull(script);
2020-12-11 16:44:27 +00:00
Assert.AreEqual("path-2\\test-path-3.js".Replace("\\", $"{Path.DirectorySeparatorChar}"), script.Path);
2018-06-29 19:52:40 +02:00
Assert.AreEqual("/scripts/path-2/test-path-3.js", script.VirtualPath);
script = new Script("\\test-path-4.js") { Content = "// script" };
Assert.Throws<UnauthorizedAccessException>(() => // fixed in 7.3 - 7.2.8 used to strip the \
repository.Save(script));
2018-06-29 19:52:40 +02:00
script = repository.Get("missing.js");
Assert.IsNull(script);
// fixed in 7.3 - 7.2.8 used to...
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-07-20 09:49:05 +02:00
private void Purge(IFileSystem fs, string path)
2018-06-29 19:52:40 +02:00
{
IEnumerable<string> files = fs.GetFiles(path, "*.js");
foreach (string file in files)
2018-06-29 19:52:40 +02:00
{
fs.DeleteFile(file);
}
IEnumerable<string> dirs = fs.GetDirectories(path);
foreach (string dir in dirs)
2018-06-29 19:52:40 +02:00
{
Purge(fs, dir);
fs.DeleteDirectory(dir);
}
}
protected Stream CreateStream(string contents = null)
{
if (string.IsNullOrEmpty(contents))
{
2018-06-29 19:52:40 +02:00
contents = "/* test */";
}
2018-06-29 19:52:40 +02:00
byte[] bytes = Encoding.UTF8.GetBytes(contents);
2018-06-29 19:52:40 +02:00
var stream = new MemoryStream(bytes);
return stream;
}
}
}