2020-12-23 11:35:49 +01:00
// Copyright (c) Umbraco.
// See LICENSE for more details.
using System ;
using System.Collections.Generic ;
2019-10-06 11:32:37 +02:00
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 ;
2018-11-23 16:19:03 +01:00
using Moq ;
2018-06-29 19:52:40 +02:00
using NUnit.Framework ;
2021-02-09 10:22:42 +01:00
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 ;
2021-02-10 14:45:44 +01:00
using Umbraco.Cms.Tests.Common.Testing ;
2018-06-29 19:52:40 +02:00
using Umbraco.Core.Models ;
2019-11-12 13:33:02 +11:00
using Umbraco.Core.Persistence.Repositories ;
2018-06-29 19:52:40 +02:00
using Umbraco.Core.Persistence.Repositories.Implement ;
2020-10-22 13:08:04 +02:00
using Umbraco.Tests.Integration.Implementations ;
using Umbraco.Tests.Integration.Testing ;
2018-06-29 19:52:40 +02:00
2020-10-22 13:08:04 +02:00
namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Persistence.Repositories
2018-06-29 19:52:40 +02:00
{
[TestFixture]
2020-11-27 19:39:43 +01:00
[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
{
2018-07-20 09:49:05 +02:00
private IFileSystems _fileSystems ;
2018-06-29 19:52:40 +02:00
private IFileSystem _fileSystem ;
2020-10-23 13:58:30 +02:00
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
{
2018-07-20 09:49:05 +02:00
_fileSystems = Mock . Of < IFileSystems > ( ) ;
2020-12-23 11:35:49 +01:00
string path = HostingEnvironment . MapPathWebRoot ( GlobalSettings . UmbracoCssPath ) ;
2020-11-27 20:34:48 +01:00
_fileSystem = new PhysicalFileSystem ( IOHelper , HostingEnvironment , GetRequiredService < ILogger < PhysicalFileSystem > > ( ) , path , "/css" ) ;
2018-07-20 09:49:05 +02:00
Mock . Get ( _fileSystems ) . Setup ( x = > x . StylesheetsFileSystem ) . Returns ( _fileSystem ) ;
2020-12-23 11:35:49 +01:00
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 ( )
{
2020-12-23 11:35:49 +01:00
// Delete all files
Purge ( ( PhysicalFileSystem ) _fileSystem , string . Empty ) ;
2020-10-22 13:08:04 +02:00
_fileSystem = null ;
}
2019-11-12 13:33:02 +11:00
private IStylesheetRepository CreateRepository ( )
{
2020-09-21 21:06:24 +02:00
var globalSettings = new GlobalSettings ( ) ;
2020-11-27 20:34:48 +01:00
return new StylesheetRepository ( GetRequiredService < ILogger < StylesheetRepository > > ( ) , _fileSystems , IOHelper , Microsoft . Extensions . Options . Options . Create ( globalSettings ) ) ;
2019-11-12 13:33:02 +11:00
}
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
2020-12-23 11:35:49 +01:00
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
{
2020-12-23 11:35:49 +01: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
2020-12-23 11:35:49 +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
{
2020-12-23 11:35:49 +01: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
2020-12-23 11:35:49 +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
2020-12-23 11:35:49 +01:00
IStylesheet stylesheetUpdated = repository . Get ( "test-update.css" ) ;
2018-06-29 19:52:40 +02:00
2020-12-23 11:35:49 +01: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
{
2020-12-23 11:35:49 +01:00
IStylesheetRepository repository = CreateRepository ( ) ;
2018-06-29 19:52:40 +02:00
// Act
2019-11-12 13:33:02 +11:00
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
2020-12-23 11:35:49 +01:00
// re-get
2018-06-29 19:52:40 +02:00
stylesheet = repository . Get ( stylesheet . Name ) ;
2020-12-23 11:35:49 +01:00
// 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
{
2020-12-23 11:35:49 +01: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
{
2020-12-23 11:35:49 +01: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
2020-12-23 11:35:49 +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
{
2020-12-23 11:35:49 +01:00
IStylesheetRepository repository = CreateRepository ( ) ;
2018-06-29 19:52:40 +02:00
// Act
2020-12-23 11:35:49 +01:00
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;}" ) ) ;
2020-12-23 11:35:49 +01:00
//// 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
{
2020-12-23 11:35:49 +01: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
2020-12-23 11:35:49 +01:00
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
{
2020-12-23 11:35:49 +01: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
2020-12-23 11:35:49 +01:00
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
{
2020-12-23 11:35:49 +01:00
IStylesheetRepository repository = CreateRepository ( ) ;
2018-06-29 19:52:40 +02:00
// Act
2020-12-23 11:35:49 +01:00
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
{
2020-12-23 11:35:49 +01:00
IStylesheetRepository repository = CreateRepository ( ) ;
2018-06-29 19:52:40 +02:00
2019-11-12 13:33:02 +11: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" ) ) ;
2020-12-23 11:35:49 +01:00
Assert . AreEqual ( "path-2\\test-path-2.css" . Replace ( "\\" , $"{Path.DirectorySeparatorChar}" ) , stylesheet . Path ) ; // fixed in 7.3 - 7.2.8 does not update the 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;}" } ;
2019-10-06 11:32:37 +02:00
Assert . Throws < UnauthorizedAccessException > ( ( ) = > // fixed in 7.3 - 7.2.8 used to strip the \
2020-12-23 11:35:49 +01:00
repository . Save ( stylesheet ) ) ;
2018-06-29 19:52:40 +02:00
// fixed in 7.3 - 7.2.8 used to throw
stylesheet = repository . Get ( "missing.css" ) ;
Assert . IsNull ( stylesheet ) ;
2020-03-25 03:04:38 +10:00
// #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
2020-06-05 11:36:59 +02:00
Assert . IsNull ( stylesheet ) ;
2018-06-29 19:52:40 +02:00
}
}
private void Purge ( PhysicalFileSystem fs , string path )
{
2020-12-23 11:35:49 +01:00
IEnumerable < string > files = fs . GetFiles ( path , "*.css" ) ;
foreach ( string file in files )
2018-06-29 19:52:40 +02:00
{
fs . DeleteFile ( file ) ;
}
2020-12-23 11:35:49 +01:00
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 ) )
2020-12-23 11:35:49 +01:00
{
2018-06-29 19:52:40 +02:00
contents = "/* test */" ;
2020-12-23 11:35:49 +01:00
}
2018-06-29 19:52:40 +02:00
2020-12-23 11:35:49 +01:00
byte [ ] bytes = Encoding . UTF8 . GetBytes ( contents ) ;
2018-06-29 19:52:40 +02:00
var stream = new MemoryStream ( bytes ) ;
return stream ;
}
}
}