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

358 lines
14 KiB
C#
Raw Normal View History

// Copyright (c) Umbraco.
// See LICENSE for more details.
using System;
using System.Collections.Generic;
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
2018-06-29 19:52:40 +02:00
{
[TestFixture]
[UmbracoTest(Database = UmbracoTestOptions.Database.None, Logger = UmbracoTestOptions.Logger.Console)]
2020-10-22 13:08:04 +02:00
public class StylesheetRepositoryTest : UmbracoIntegrationTest
2018-06-29 19:52:40 +02:00
{
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;
private IHostingEnvironment HostingEnvironment => GetRequiredService<IHostingEnvironment>();
2018-06-29 19:52:40 +02:00
2020-10-22 13:08:04 +02:00
[SetUp]
public void SetUpFileSystem()
2018-06-29 19:52:40 +02:00
{
string path = HostingEnvironment.MapPathWebRoot(GlobalSettings.UmbracoCssPath);
_fileSystem = new PhysicalFileSystem(IOHelper, HostingEnvironment, GetRequiredService<ILogger<PhysicalFileSystem>>(), path, "/css");
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, _fileSystem, null, null);
Stream stream = CreateStream("body {background:#EE7600; color:#FFF;}");
2018-06-29 19:52:40 +02:00
_fileSystem.AddFile("styles.css", stream);
}
2020-10-22 13:08:04 +02:00
[TearDown]
public void TearDownFileSystem()
{
// Delete all files
Purge((PhysicalFileSystem)_fileSystem, string.Empty);
2020-10-22 13:08:04 +02:00
_fileSystem = null;
}
private IStylesheetRepository CreateRepository()
{
2020-09-21 21:06:24 +02:00
var globalSettings = new GlobalSettings();
return new StylesheetRepository(_fileSystems);
}
2018-06-29 19:52:40 +02:00
[Test]
public void Can_Instantiate_Repository()
{
// Arrange
2018-07-20 09:49:05 +02:00
using (ScopeProvider.CreateScope())
2018-06-29 19:52:40 +02:00
{
// Act
IStylesheetRepository repository = CreateRepository();
2018-06-29 19:52:40 +02:00
// Assert
Assert.That(repository, Is.Not.Null);
}
}
[Test]
public void Can_Perform_Add()
{
// Arrange
2018-07-20 09:49:05 +02:00
using (ScopeProvider.CreateScope())
2018-06-29 19:52:40 +02:00
{
IStylesheetRepository 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);
2018-11-23 16:19:03 +01:00
// Assert
2018-06-29 19:52:40 +02:00
Assert.That(_fileSystem.FileExists("test-add.css"), Is.True);
}
}
[Test]
public void Can_Perform_Update()
{
// Arrange
2018-07-20 09:49:05 +02:00
using (ScopeProvider.CreateScope())
2018-06-29 19:52:40 +02:00
{
IStylesheetRepository 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
IStylesheet stylesheetUpdate = repository.Get("test-update.css");
2018-06-29 19:52:40 +02:00
stylesheetUpdate.Content = "body { color:#000; }";
repository.Save(stylesheetUpdate);
2018-11-23 16:19:03 +01:00
IStylesheet stylesheetUpdated = repository.Get("test-update.css");
2018-06-29 19:52:40 +02:00
// Assert
2018-06-29 19:52:40 +02:00
Assert.That(stylesheetUpdated, Is.Not.Null);
Assert.That(stylesheetUpdated.HasIdentity, Is.True);
Assert.That(stylesheetUpdated.Content, Is.EqualTo("body { color:#000; }"));
}
}
[Test]
public void Can_Perform_Update_With_Property()
{
// Arrange
2018-07-20 09:49:05 +02:00
using (ScopeProvider.CreateScope())
2018-06-29 19:52:40 +02:00
{
IStylesheetRepository 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;}" };
2018-06-29 19:52:40 +02:00
repository.Save(stylesheet);
2018-11-23 16:19:03 +01:00
2018-06-29 19:52:40 +02:00
stylesheet.AddProperty(new StylesheetProperty("Test", "p", "font-size:2em;"));
repository.Save(stylesheet);
2018-11-23 16:19:03 +01:00
// re-get
2018-06-29 19:52:40 +02:00
stylesheet = repository.Get(stylesheet.Name);
// Assert
2020-12-11 16:44:27 +00:00
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)));
2018-06-29 19:52:40 +02:00
Assert.AreEqual(1, stylesheet.Properties.Count());
}
}
[Test]
public void Throws_When_Adding_Duplicate_Properties()
{
// Arrange
2018-07-20 09:49:05 +02:00
using (ScopeProvider.CreateScope())
2018-06-29 19:52:40 +02:00
{
IStylesheetRepository 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
2018-06-29 19:52:40 +02:00
stylesheet.AddProperty(new StylesheetProperty("Test", "p", "font-size:2em;"));
Assert.Throws<DuplicateNameException>(() => stylesheet.AddProperty(new StylesheetProperty("test", "p", "font-size:2em;")));
}
}
[Test]
public void Can_Perform_Delete()
{
// Arrange
2018-07-20 09:49:05 +02:00
using (ScopeProvider.CreateScope())
2018-06-29 19:52:40 +02:00
{
IStylesheetRepository 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
2018-06-29 19:52:40 +02:00
repository.Delete(stylesheet);
2018-11-23 16:19:03 +01:00
// Assert
2018-06-29 19:52:40 +02:00
Assert.That(_fileSystem.FileExists("test-delete.css"), Is.False);
}
}
[Test]
public void Can_Perform_Get()
{
// Arrange
2018-07-20 09:49:05 +02:00
using (ScopeProvider.CreateScope())
2018-06-29 19:52:40 +02:00
{
IStylesheetRepository repository = CreateRepository();
2018-06-29 19:52:40 +02:00
// Act
IStylesheet stylesheet = repository.Get("styles.css");
2018-06-29 19:52:40 +02:00
// 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
}
}
[Test]
public void Can_Perform_GetAll()
{
// Arrange
2018-07-20 09:49:05 +02:00
using (ScopeProvider.CreateScope())
2018-06-29 19:52:40 +02:00
{
IStylesheetRepository repository = CreateRepository();
2018-06-29 19:52:40 +02:00
var stylesheet = new Stylesheet("styles-v2.css") { Content = "body { color:#000; } .bold {font-weight:bold;}" };
repository.Save(stylesheet);
2018-11-23 16:19:03 +01:00
2018-06-29 19:52:40 +02:00
// Act
IEnumerable<IStylesheet> stylesheets = repository.GetMany();
2018-06-29 19:52:40 +02:00
// 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));
}
}
[Test]
public void Can_Perform_GetAll_With_Params()
{
// Arrange
2018-07-20 09:49:05 +02:00
using (ScopeProvider.CreateScope())
2018-06-29 19:52:40 +02:00
{
IStylesheetRepository repository = CreateRepository();
2018-06-29 19:52:40 +02:00
var stylesheet = new Stylesheet("styles-v2.css") { Content = "body { color:#000; } .bold {font-weight:bold;}" };
repository.Save(stylesheet);
2018-11-23 16:19:03 +01:00
2018-06-29 19:52:40 +02:00
// Act
IEnumerable<IStylesheet> stylesheets = repository.GetMany("styles-v2.css", "styles.css");
2018-06-29 19:52:40 +02:00
// 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));
}
}
[Test]
public void Can_Perform_Exists()
{
// Arrange
2018-07-20 09:49:05 +02:00
using (ScopeProvider.CreateScope())
2018-06-29 19:52:40 +02:00
{
IStylesheetRepository repository = CreateRepository();
2018-06-29 19:52:40 +02:00
// Act
bool exists = repository.Exists("styles.css");
2018-06-29 19:52:40 +02:00
// Assert
Assert.That(exists, Is.True);
}
}
[Test]
public void PathTests()
{
// unless noted otherwise, no changes / 7.2.8
2018-07-20 09:49:05 +02:00
using (ScopeProvider.CreateScope())
2018-06-29 19:52:40 +02:00
{
IStylesheetRepository repository = CreateRepository();
2018-06-29 19:52:40 +02:00
IStylesheet stylesheet = new Stylesheet("test-path-1.css") { Content = "body { color:#000; } .bold {font-weight:bold;}" };
2018-06-29 19:52:40 +02:00
repository.Save(stylesheet);
2018-11-23 16:19:03 +01:00
2018-06-29 19:52:40 +02:00
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);
2018-11-23 16:19:03 +01:00
2018-06-29 19:52:40 +02:00
Assert.IsTrue(_fileSystem.FileExists("path-2/test-path-2.css"));
Assert.AreEqual("path-2\\test-path-2.css".Replace("\\", $"{Path.DirectorySeparatorChar}"), stylesheet.Path);
2018-06-29 19:52:40 +02:00
Assert.AreEqual("/css/path-2/test-path-2.css", stylesheet.VirtualPath);
stylesheet = repository.Get("path-2/test-path-2.css");
Assert.IsNotNull(stylesheet);
2020-12-11 16:44:27 +00:00
Assert.AreEqual("path-2\\test-path-2.css".Replace("\\", $"{Path.DirectorySeparatorChar}"), stylesheet.Path);
2018-06-29 19:52:40 +02:00
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);
2018-11-23 16:19:03 +01:00
2018-06-29 19:52:40 +02:00
Assert.IsTrue(_fileSystem.FileExists("path-2/test-path-3.css"));
2020-12-11 16:44:27 +00:00
Assert.AreEqual("path-2\\test-path-3.css".Replace("\\", $"{Path.DirectorySeparatorChar}"), stylesheet.Path);
2018-06-29 19:52:40 +02:00
Assert.AreEqual("/css/path-2/test-path-3.css", stylesheet.VirtualPath);
stylesheet = repository.Get("path-2/test-path-3.css");
Assert.IsNotNull(stylesheet);
2020-12-11 16:44:27 +00:00
Assert.AreEqual("path-2\\test-path-3.css".Replace("\\", $"{Path.DirectorySeparatorChar}"), stylesheet.Path);
2018-06-29 19:52:40 +02:00
Assert.AreEqual("/css/path-2/test-path-3.css", stylesheet.VirtualPath);
stylesheet = repository.Get("path-2\\test-path-3.css");
Assert.IsNotNull(stylesheet);
2020-12-11 16:44:27 +00:00
Assert.AreEqual("path-2\\test-path-3.css".Replace("\\", $"{Path.DirectorySeparatorChar}"), stylesheet.Path);
2018-06-29 19:52:40 +02:00
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));
2018-06-29 19:52:40 +02:00
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);
2018-06-29 19:52:40 +02:00
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
}
}
private void Purge(PhysicalFileSystem fs, string path)
{
IEnumerable<string> files = fs.GetFiles(path, "*.css");
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;
}
}
}