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

379 lines
13 KiB
C#
Raw Normal View History

// Copyright (c) Umbraco.
// See LICENSE for more details.
using System.Data;
2018-06-29 19:52:40 +02:00
using System.IO;
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, Logger = UmbracoTestOptions.Logger.Console)]
public class StylesheetRepositoryTest : UmbracoIntegrationTest
2018-06-29 19:52:40 +02:00
{
[SetUp]
public void SetUpFileSystem()
2018-06-29 19:52:40 +02:00
{
var path = HostingEnvironment.MapPathWebRoot(GlobalSettings.UmbracoCssPath);
_fileSystem = new PhysicalFileSystem(IOHelper, HostingEnvironment, GetRequiredService<ILogger<PhysicalFileSystem>>(), path, "/css");
_fileSystems = FileSystemsCreator.CreateTestFileSystems(
LoggerFactory,
IOHelper,
GetRequiredService<IOptions<GlobalSettings>>(),
HostingEnvironment,
null,
null,
_fileSystem,
null,
null);
var stream = CreateStream("body {background:#EE7600; color:#FFF;}");
_fileSystem.AddFile("styles.css", stream);
}
[TearDown]
public void TearDownFileSystem()
{
// Delete all files
Purge((PhysicalFileSystem)_fileSystem, string.Empty);
_fileSystem = null;
}
2018-06-29 19:52:40 +02:00
private FileSystems _fileSystems;
private IFileSystem _fileSystem;
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 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 IStylesheetRepository CreateRepository()
{
var globalSettings = new GlobalSettings();
return new StylesheetRepository(_fileSystems);
}
2018-06-29 19:52:40 +02:00
[Test]
public void Can_Instantiate_Repository()
{
// Arrange
using (ScopeProvider.CreateScope())
2020-10-22 13:08:04 +02:00
{
// Act
var repository = CreateRepository();
2020-10-22 13:08:04 +02:00
// Assert
Assert.That(repository, Is.Not.Null);
}
}
[Test]
public void Can_Perform_Add()
{
// Arrange
using (ScopeProvider.CreateScope())
2018-06-29 19:52:40 +02:00
{
var repository = CreateRepository();
2018-06-29 19:52:40 +02:00
// Act
var stylesheet =
new Stylesheet("test-add.css") { Content = "body { color:#000; } .bold {font-weight:bold;}" };
repository.Save(stylesheet);
// Assert
Assert.That(_fileSystem.FileExists("test-add.css"), Is.True);
2018-06-29 19:52:40 +02:00
}
}
2018-06-29 19:52:40 +02:00
[Test]
public void Can_Perform_Update()
{
// Arrange
using (ScopeProvider.CreateScope())
2018-06-29 19:52:40 +02:00
{
var repository = CreateRepository();
// Act
var stylesheet =
new Stylesheet("test-update.css") { Content = "body { color:#000; } .bold {font-weight:bold;}" };
repository.Save(stylesheet);
var stylesheetUpdate = repository.Get("test-update.css");
stylesheetUpdate.Content = "body { color:#000; }";
repository.Save(stylesheetUpdate);
var stylesheetUpdated = repository.Get("test-update.css");
// Assert
Assert.That(stylesheetUpdated, Is.Not.Null);
Assert.That(stylesheetUpdated.HasIdentity, Is.True);
Assert.That(stylesheetUpdated.Content, Is.EqualTo("body { color:#000; }"));
2018-06-29 19:52:40 +02:00
}
}
2018-06-29 19:52:40 +02:00
[Test]
public void Can_Perform_Update_With_Property()
{
// Arrange
using (ScopeProvider.CreateScope())
2018-06-29 19:52:40 +02:00
{
var repository = CreateRepository();
2018-06-29 19:52:40 +02:00
// Act
IStylesheet stylesheet =
new Stylesheet("test-update.css") { Content = "body { color:#000; } .bold {font-weight:bold;}" };
repository.Save(stylesheet);
2018-11-23 16:19:03 +01:00
stylesheet.AddProperty(new StylesheetProperty("Test", "p", "font-size:2em;"));
2018-06-29 19:52:40 +02:00
repository.Save(stylesheet);
2018-11-23 16:19:03 +01:00
// re-get
stylesheet = repository.Get(stylesheet.Name);
2018-06-29 19:52:40 +02:00
// Assert
Assert.That(
stylesheet.Content,
Is.EqualTo(
"body { color:#000; } .bold {font-weight:bold;}\r\n\r\n/**umb_name:Test*/\r\np {\r\n\tfont-size:2em;\r\n}"
.Replace("\r\n", Environment.NewLine)));
Assert.AreEqual(1, stylesheet.Properties.Count());
2018-06-29 19:52:40 +02:00
}
}
2018-06-29 19:52:40 +02:00
[Test]
public void Throws_When_Adding_Duplicate_Properties()
{
// Arrange
using (ScopeProvider.CreateScope())
2018-06-29 19:52:40 +02:00
{
var repository = CreateRepository();
2018-06-29 19:52:40 +02:00
// Act
var stylesheet =
new Stylesheet("test-update.css") { Content = "body { color:#000; } .bold {font-weight:bold;}" };
repository.Save(stylesheet);
2018-11-23 16:19:03 +01:00
stylesheet.AddProperty(new StylesheetProperty("Test", "p", "font-size:2em;"));
2018-06-29 19:52:40 +02:00
Assert.Throws<DuplicateNameException>(() =>
stylesheet.AddProperty(new StylesheetProperty("test", "p", "font-size:2em;")));
2018-06-29 19:52:40 +02:00
}
}
2018-06-29 19:52:40 +02:00
[Test]
public void Can_Perform_Delete()
{
// Arrange
using (ScopeProvider.CreateScope())
2018-06-29 19:52:40 +02:00
{
var repository = CreateRepository();
2018-06-29 19:52:40 +02:00
// Act
var stylesheet =
new Stylesheet("test-delete.css") { Content = "body { color:#000; } .bold {font-weight:bold;}" };
repository.Save(stylesheet);
2018-11-23 16:19:03 +01:00
repository.Delete(stylesheet);
2018-11-23 16:19:03 +01:00
// Assert
Assert.That(_fileSystem.FileExists("test-delete.css"), Is.False);
2018-06-29 19:52:40 +02:00
}
}
2018-06-29 19:52:40 +02:00
[Test]
public void Can_Perform_Get()
{
// Arrange
using (ScopeProvider.CreateScope())
2018-06-29 19:52:40 +02:00
{
var repository = CreateRepository();
// Act
var stylesheet = repository.Get("styles.css");
// Assert
Assert.That(stylesheet, Is.Not.Null);
Assert.That(stylesheet.HasIdentity, Is.True);
Assert.That(stylesheet.Content, Is.EqualTo("body {background:#EE7600; color:#FFF;}"));
//// Assert.That(repository.ValidateStylesheet(stylesheet), Is.True); //TODO this can't be activated before we handle file systems correct
2018-06-29 19:52:40 +02:00
}
}
2018-06-29 19:52:40 +02:00
[Test]
public void Can_Perform_GetAll()
{
// Arrange
using (ScopeProvider.CreateScope())
2018-06-29 19:52:40 +02:00
{
var repository = CreateRepository();
var stylesheet =
new Stylesheet("styles-v2.css") { Content = "body { color:#000; } .bold {font-weight:bold;}" };
repository.Save(stylesheet);
// Act
var stylesheets = repository.GetMany().ToArray();
// Assert
Assert.That(stylesheets, Is.Not.Null);
Assert.That(stylesheets.Any(), Is.True);
Assert.That(stylesheets.Any(x => x == null), Is.False);
Assert.That(stylesheets.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_GetAll_With_Params()
{
// Arrange
using (ScopeProvider.CreateScope())
2018-06-29 19:52:40 +02:00
{
var repository = CreateRepository();
var stylesheet =
new Stylesheet("styles-v2.css") { Content = "body { color:#000; } .bold {font-weight:bold;}" };
repository.Save(stylesheet);
// Act
var stylesheets = repository.GetMany("styles-v2.css", "styles.css").ToArray();
// Assert
Assert.That(stylesheets, Is.Not.Null);
Assert.That(stylesheets.Any(), Is.True);
Assert.That(stylesheets.Any(x => x == null), Is.False);
Assert.That(stylesheets.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()
{
// Arrange
using (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("styles.css");
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 PathTests()
{
// unless noted otherwise, no changes / 7.2.8
using (ScopeProvider.CreateScope())
2018-06-29 19:52:40 +02:00
{
var repository = CreateRepository();
IStylesheet stylesheet =
new Stylesheet("test-path-1.css") { Content = "body { color:#000; } .bold {font-weight:bold;}" };
repository.Save(stylesheet);
Assert.IsTrue(_fileSystem.FileExists("test-path-1.css"));
Assert.AreEqual("test-path-1.css", stylesheet.Path);
Assert.AreEqual("/css/test-path-1.css", stylesheet.VirtualPath);
stylesheet =
new Stylesheet("path-2/test-path-2.css") { Content = "body { color:#000; } .bold {font-weight:bold;}" };
repository.Save(stylesheet);
Assert.IsTrue(_fileSystem.FileExists("path-2/test-path-2.css"));
Assert.AreEqual("path-2\\test-path-2.css".Replace("\\", $"{Path.DirectorySeparatorChar}"), stylesheet.Path);
Assert.AreEqual("/css/path-2/test-path-2.css", stylesheet.VirtualPath);
stylesheet = repository.Get("path-2/test-path-2.css");
Assert.IsNotNull(stylesheet);
Assert.AreEqual("path-2\\test-path-2.css".Replace("\\", $"{Path.DirectorySeparatorChar}"), stylesheet.Path);
Assert.AreEqual("/css/path-2/test-path-2.css", stylesheet.VirtualPath);
stylesheet =
new Stylesheet("path-2\\test-path-3.css") { Content = "body { color:#000; } .bold {font-weight:bold;}" };
repository.Save(stylesheet);
Assert.IsTrue(_fileSystem.FileExists("path-2/test-path-3.css"));
Assert.AreEqual("path-2\\test-path-3.css".Replace("\\", $"{Path.DirectorySeparatorChar}"), stylesheet.Path);
Assert.AreEqual("/css/path-2/test-path-3.css", stylesheet.VirtualPath);
stylesheet = repository.Get("path-2/test-path-3.css");
Assert.IsNotNull(stylesheet);
Assert.AreEqual("path-2\\test-path-3.css".Replace("\\", $"{Path.DirectorySeparatorChar}"), stylesheet.Path);
Assert.AreEqual("/css/path-2/test-path-3.css", stylesheet.VirtualPath);
stylesheet = repository.Get("path-2\\test-path-3.css");
Assert.IsNotNull(stylesheet);
Assert.AreEqual("path-2\\test-path-3.css".Replace("\\", $"{Path.DirectorySeparatorChar}"), stylesheet.Path);
Assert.AreEqual("/css/path-2/test-path-3.css", stylesheet.VirtualPath);
stylesheet =
new Stylesheet("..\\test-path-4.css") { Content = "body { color:#000; } .bold {font-weight:bold;}" };
Assert.Throws<UnauthorizedAccessException>(() =>
repository.Save(stylesheet));
stylesheet =
new Stylesheet("\\test-path-5.css") { Content = "body { color:#000; } .bold {font-weight:bold;}" };
repository.Save(stylesheet);
stylesheet = repository.Get("\\test-path-5.css");
Assert.IsNotNull(stylesheet);
Assert.AreEqual("test-path-5.css", stylesheet.Path);
Assert.AreEqual("/css/test-path-5.css", stylesheet.VirtualPath);
stylesheet = repository.Get("missing.css");
Assert.IsNull(stylesheet);
// #7713 changes behaviour to return null when outside the filesystem
// to accomodate changing the CSS path and not flooding the backoffice with errors
stylesheet = repository.Get("..\\test-path-4.css"); // outside the filesystem, does not exist
Assert.IsNull(stylesheet);
stylesheet = repository.Get("../packages.config"); // outside the filesystem, exists
Assert.IsNull(stylesheet);
2018-06-29 19:52:40 +02:00
}
}
2018-06-29 19:52:40 +02:00
private void Purge(PhysicalFileSystem fs, string path)
{
var files = fs.GetFiles(path, "*.css");
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
}
}