Skip to content

Commit

Permalink
Merge pull request #6807 from umbraco/v8/feature/AB2461-media-tracking
Browse files Browse the repository at this point in the history
Splits up TemplateUtilities into testable parts, creates new GetReferences API
  • Loading branch information
bergmania authored Oct 23, 2019
2 parents 1362a95 + c831c9d commit 9980904
Show file tree
Hide file tree
Showing 29 changed files with 860 additions and 376 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
internal sealed class ContentRepositoryBase
{
/// <summary>
///
/// This is used for unit tests ONLY
/// </summary>
public static bool ThrowOnWarning = false;
Expand All @@ -43,7 +44,7 @@ protected ContentRepositoryBase(IScopeAccessor scopeAccessor, AppCaches cache, I

protected ILanguageRepository LanguageRepository { get; }

protected PropertyEditorCollection PropertyEditors => Current.PropertyEditors; // TODO: inject
protected PropertyEditorCollection PropertyEditors => Current.PropertyEditors; // TODO: inject ... this causes circular refs, not sure which refs they are though

#region Versions

Expand Down
19 changes: 19 additions & 0 deletions src/Umbraco.Core/PropertyEditors/IDataValueEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

namespace Umbraco.Core.PropertyEditors
{

/// <summary>
/// Represents an editor for editing data values.
/// </summary>
Expand Down Expand Up @@ -63,8 +64,26 @@ public interface IDataValueEditor

// TODO: / deal with this when unplugging the xml cache
// why property vs propertyType? services should be injected! etc...

/// <summary>
/// Used for serializing an <see cref="IContent"/> item for packaging
/// </summary>
/// <param name="property"></param>
/// <param name="dataTypeService"></param>
/// <param name="localizationService"></param>
/// <param name="published"></param>
/// <returns></returns>
IEnumerable<XElement> ConvertDbToXml(Property property, IDataTypeService dataTypeService, ILocalizationService localizationService, bool published);

/// <summary>
/// Used for serializing an <see cref="IContent"/> item for packaging
/// </summary>
/// <param name="propertyType"></param>
/// <param name="value"></param>
/// <param name="dataTypeService"></param>
/// <returns></returns>
XNode ConvertDbToXml(PropertyType propertyType, object value, IDataTypeService dataTypeService);

string ConvertDbToString(PropertyType propertyType, object value, IDataTypeService dataTypeService);
}
}
17 changes: 17 additions & 0 deletions src/Umbraco.Core/PropertyEditors/IDataValueReference.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System.Collections.Generic;

namespace Umbraco.Core.PropertyEditors
{
/// <summary>
/// Resolve references from <see cref="IDataValueEditor"/> values
/// </summary>
public interface IDataValueReference
{
/// <summary>
/// Returns any references contained in the value
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
IEnumerable<Udi> GetReferences(object value);
}
}
2 changes: 1 addition & 1 deletion src/Umbraco.Core/Udi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ private static void EnsureScanForUdiTypes()
// just pick every service connectors - just making sure that not two of them
// would register the same entity type, with different udi types (would not make
// much sense anyways).
var connectors = Current.TypeLoader.GetTypes<IServiceConnector>();
var connectors = Current.HasFactory ? (Current.TypeLoader?.GetTypes<IServiceConnector>() ?? Enumerable.Empty<Type>()) : Enumerable.Empty<Type>();
var result = new Dictionary<string, UdiType>();
foreach (var connector in connectors)
{
Expand Down
1 change: 1 addition & 0 deletions src/Umbraco.Core/Umbraco.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@
<Compile Include="Models\PublishedContent\IPublishedContentType.cs" />
<Compile Include="Models\PublishedContent\IPublishedPropertyType.cs" />
<Compile Include="PropertyEditors\ConfigurationFieldsExtensions.cs" />
<Compile Include="PropertyEditors\IDataValueReference.cs" />
<Compile Include="PropertyEditors\IIgnoreUserStartNodesConfig.cs" />
<Compile Include="PublishedContentExtensions.cs" />
<Compile Include="Models\PublishedContent\UrlMode.cs" />
Expand Down
1 change: 1 addition & 0 deletions src/Umbraco.Tests/PropertyEditors/ImageCropperTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

namespace Umbraco.Tests.PropertyEditors
{

[TestFixture]
public class ImageCropperTest
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using Umbraco.Web.PropertyEditors;
using Umbraco.Core.Services;
using Umbraco.Web;
using Umbraco.Web.Templates;

namespace Umbraco.Tests.PublishedContent
{
Expand Down Expand Up @@ -38,9 +39,13 @@ protected override void Initialize()
base.Initialize();

var converters = Factory.GetInstance<PropertyValueConverterCollection>();
var umbracoContextAccessor = Mock.Of<IUmbracoContextAccessor>();
var logger = Mock.Of<ILogger>();

var imageSourceParser = new HtmlImageSourceParser(umbracoContextAccessor, logger, Mock.Of<IMediaService>(), Mock.Of<IContentTypeBaseServiceProvider>());
var localLinkParser = new HtmlLocalLinkParser(umbracoContextAccessor);
var dataTypeService = new TestObjects.TestDataTypeService(
new DataType(new RichTextPropertyEditor(Mock.Of<ILogger>(), Mock.Of<IMediaService>(), Mock.Of<IContentTypeBaseServiceProvider>(), Mock.Of<IUmbracoContextAccessor>())) { Id = 1 });
new DataType(new RichTextPropertyEditor(logger, umbracoContextAccessor, imageSourceParser, localLinkParser)) { Id = 1 });

var publishedContentTypeFactory = new PublishedContentTypeFactory(Mock.Of<IPublishedModelFactory>(), converters, dataTypeService);

Expand Down
5 changes: 4 additions & 1 deletion src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
using Umbraco.Tests.Testing;
using Umbraco.Web.Models.PublishedContent;
using Umbraco.Web.PropertyEditors;
using Umbraco.Web.Templates;

namespace Umbraco.Tests.PublishedContent
{
Expand All @@ -45,11 +46,13 @@ protected override void Compose()
var mediaService = Mock.Of<IMediaService>();
var contentTypeBaseServiceProvider = Mock.Of<IContentTypeBaseServiceProvider>();
var umbracoContextAccessor = Mock.Of<IUmbracoContextAccessor>();
var imageSourceParser = new HtmlImageSourceParser(umbracoContextAccessor, logger, mediaService, contentTypeBaseServiceProvider);
var linkParser = new HtmlLocalLinkParser(umbracoContextAccessor);

var dataTypeService = new TestObjects.TestDataTypeService(
new DataType(new VoidEditor(logger)) { Id = 1 },
new DataType(new TrueFalsePropertyEditor(logger)) { Id = 1001 },
new DataType(new RichTextPropertyEditor(logger, mediaService, contentTypeBaseServiceProvider, umbracoContextAccessor)) { Id = 1002 },
new DataType(new RichTextPropertyEditor(logger, umbracoContextAccessor, imageSourceParser, linkParser)) { Id = 1002 },
new DataType(new IntegerPropertyEditor(logger)) { Id = 1003 },
new DataType(new TextboxPropertyEditor(logger)) { Id = 1004 },
new DataType(new MediaPickerPropertyEditor(logger)) { Id = 1005 });
Expand Down
119 changes: 119 additions & 0 deletions src/Umbraco.Tests/Templates/ImageSourceParserTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
using Umbraco.Core.Logging;
using Moq;
using NUnit.Framework;
using Umbraco.Core.Services;
using Umbraco.Tests.Testing.Objects.Accessors;
using Umbraco.Web.Templates;
using Umbraco.Web;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Web.Routing;
using Umbraco.Tests.Testing.Objects;
using System.Web;
using System;
using System.Linq;
using Umbraco.Core.Models;
using Umbraco.Core;

namespace Umbraco.Tests.Templates
{


[TestFixture]
public class ImageSourceParserTests
{
[Test]
public void Returns_Udis_From_Data_Udi_Html_Attributes()
{
var input = @"<p>
<div>
<img src='/media/12312.jpg' data-udi='umb://media/D4B18427A1544721B09AC7692F35C264' />
</div>
</p><p><img src='/media/234234.jpg' data-udi=""umb://media-type/B726D735E4C446D58F703F3FBCFC97A5"" /></p>";

var logger = Mock.Of<ILogger>();
var umbracoContextAccessor = new TestUmbracoContextAccessor();
var imageSourceParser = new HtmlImageSourceParser(umbracoContextAccessor, logger, Mock.Of<IMediaService>(), Mock.Of<IContentTypeBaseServiceProvider>());

var result = imageSourceParser.FindUdisFromDataAttributes(input).ToList();
Assert.AreEqual(2, result.Count);
Assert.AreEqual(Udi.Parse("umb://media/D4B18427A1544721B09AC7692F35C264"), result[0]);
Assert.AreEqual(Udi.Parse("umb://media-type/B726D735E4C446D58F703F3FBCFC97A5"), result[1]);
}

[Test]
public void Remove_Image_Sources()
{
var logger = Mock.Of<ILogger>();
var umbracoContextAccessor = new TestUmbracoContextAccessor();
var imageSourceParser = new HtmlImageSourceParser(umbracoContextAccessor, logger, Mock.Of<IMediaService>(), Mock.Of<IContentTypeBaseServiceProvider>());

var result = imageSourceParser.RemoveImageSources(@"<p>
<div>
<img src=""/media/12354/test.jpg"" />
</div></p>
<p>
<div><img src=""/media/987645/test.jpg"" data-udi=""umb://media/81BB2036-034F-418B-B61F-C7160D68DCD4"" /></div>
</p>");

Assert.AreEqual(@"<p>
<div>
<img src=""/media/12354/test.jpg"" />
</div></p>
<p>
<div><img src="""" data-udi=""umb://media/81BB2036-034F-418B-B61F-C7160D68DCD4"" /></div>
</p>", result);
}

[Test]
public void Ensure_Image_Sources()
{
//setup a mock url provider which we'll use for testing

var mediaType = new PublishedContentType(777, "image", PublishedItemType.Media, Enumerable.Empty<string>(), Enumerable.Empty<PublishedPropertyType>(), ContentVariation.Nothing);
var media = new Mock<IPublishedContent>();
media.Setup(x => x.ContentType).Returns(mediaType);
var mediaUrlProvider = new Mock<IMediaUrlProvider>();
mediaUrlProvider.Setup(x => x.GetMediaUrl(It.IsAny<UmbracoContext>(), It.IsAny<IPublishedContent>(), It.IsAny<string>(), It.IsAny<UrlMode>(), It.IsAny<string>(), It.IsAny<Uri>()))
.Returns(UrlInfo.Url("/media/1001/my-image.jpg"));

var umbracoContextAccessor = new TestUmbracoContextAccessor();

var umbracoContextFactory = TestUmbracoContextFactory.Create(
mediaUrlProvider: mediaUrlProvider.Object,
umbracoContextAccessor: umbracoContextAccessor);

using (var reference = umbracoContextFactory.EnsureUmbracoContext(Mock.Of<HttpContextBase>()))
{
var mediaCache = Mock.Get(reference.UmbracoContext.Media);
mediaCache.Setup(x => x.GetById(It.IsAny<Guid>())).Returns(media.Object);

var imageSourceParser = new HtmlImageSourceParser(umbracoContextAccessor, Mock.Of<ILogger>(), Mock.Of<IMediaService>(), Mock.Of<IContentTypeBaseServiceProvider>());

var result = imageSourceParser.EnsureImageSources(@"<p>
<div>
<img src="""" />
</div></p>
<p>
<div><img src="""" data-udi=""umb://media/81BB2036-034F-418B-B61F-C7160D68DCD4"" /></div>
</p>
<p>
<div><img src=""?width=100"" data-udi=""umb://media/81BB2036-034F-418B-B61F-C7160D68DCD4"" /></div>
</p>");

Assert.AreEqual(@"<p>
<div>
<img src="""" />
</div></p>
<p>
<div><img src=""/media/1001/my-image.jpg"" data-udi=""umb://media/81BB2036-034F-418B-B61F-C7160D68DCD4"" /></div>
</p>
<p>
<div><img src=""/media/1001/my-image.jpg?width=100"" data-udi=""umb://media/81BB2036-034F-418B-B61F-C7160D68DCD4"" /></div>
</p>", result);

}


}
}
}
34 changes: 34 additions & 0 deletions src/Umbraco.Tests/Templates/LocalLinkParserTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using NUnit.Framework;
using System.Linq;
using Umbraco.Core;
using Umbraco.Tests.Testing.Objects.Accessors;
using Umbraco.Web.Templates;

namespace Umbraco.Tests.Templates
{
[TestFixture]
public class LocalLinkParserTests
{
[Test]
public void Returns_Udis_From_LocalLinks()
{
var input = @"<p>
<div>
<img src='/media/12312.jpg' data-udi='umb://media/D4B18427A1544721B09AC7692F35C264' />
<a href=""{locallink:umb://document/C093961595094900AAF9170DDE6AD442}"">hello</a>
</div>
</p><p><img src='/media/234234.jpg' data-udi=""umb://media-type/B726D735E4C446D58F703F3FBCFC97A5"" />
<a href=""{locallink:umb://document-type/2D692FCB070B4CDA92FB6883FDBFD6E2}"">hello</a>
</p>";

var umbracoContextAccessor = new TestUmbracoContextAccessor();
var parser = new HtmlLocalLinkParser(umbracoContextAccessor);

var result = parser.FindUdisFromLocalLinks(input).ToList();

Assert.AreEqual(2, result.Count);
Assert.AreEqual(Udi.Parse("umb://document/C093961595094900AAF9170DDE6AD442"), result[0]);
Assert.AreEqual(Udi.Parse("umb://document-type/2D692FCB070B4CDA92FB6883FDBFD6E2"), result[1]);
}
}
}
3 changes: 3 additions & 0 deletions src/Umbraco.Tests/Testing/Objects/TestDataSource.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.Scoping;
using Umbraco.Web;
using Umbraco.Web.PublishedCache.NuCache;
using Umbraco.Web.PublishedCache.NuCache.DataSource;

namespace Umbraco.Tests.Testing.Objects
{

internal class TestDataSource : IDataSource
{
public TestDataSource(params ContentNodeKit[] kits)
Expand Down
49 changes: 49 additions & 0 deletions src/Umbraco.Tests/Testing/Objects/TestUmbracoContextFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using Moq;
using Umbraco.Core.Configuration;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Services;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.Testing.Objects.Accessors;
using Umbraco.Web;
using Umbraco.Web.PublishedCache;
using Umbraco.Web.Routing;

namespace Umbraco.Tests.Testing.Objects
{
/// <summary>
/// Simplify creating test UmbracoContext's
/// </summary>
public class TestUmbracoContextFactory
{
public static IUmbracoContextFactory Create(IGlobalSettings globalSettings = null, IUrlProvider urlProvider = null,
IMediaUrlProvider mediaUrlProvider = null,
IUmbracoContextAccessor umbracoContextAccessor = null)
{
if (globalSettings == null) globalSettings = SettingsForTests.GenerateMockGlobalSettings();
if (urlProvider == null) urlProvider = Mock.Of<IUrlProvider>();
if (mediaUrlProvider == null) mediaUrlProvider = Mock.Of<IMediaUrlProvider>();
if (umbracoContextAccessor == null) umbracoContextAccessor = new TestUmbracoContextAccessor();

var contentCache = new Mock<IPublishedContentCache>();
var mediaCache = new Mock<IPublishedMediaCache>();
var snapshot = new Mock<IPublishedSnapshot>();
snapshot.Setup(x => x.Content).Returns(contentCache.Object);
snapshot.Setup(x => x.Media).Returns(mediaCache.Object);
var snapshotService = new Mock<IPublishedSnapshotService>();
snapshotService.Setup(x => x.CreatePublishedSnapshot(It.IsAny<string>())).Returns(snapshot.Object);

var umbracoContextFactory = new UmbracoContextFactory(
umbracoContextAccessor,
snapshotService.Object,
new TestVariationContextAccessor(),
new TestDefaultCultureAccessor(),
Mock.Of<IUmbracoSettingsSection>(section => section.WebRouting == Mock.Of<IWebRoutingSection>(routingSection => routingSection.UrlProviderMode == "Auto")),
globalSettings,
new UrlProviderCollection(new[] { urlProvider }),
new MediaUrlProviderCollection(new[] { mediaUrlProvider }),
Mock.Of<IUserService>());

return umbracoContextFactory;
}
}
}
5 changes: 5 additions & 0 deletions src/Umbraco.Tests/Testing/UmbracoTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
using Umbraco.Web.Sections;
using Current = Umbraco.Core.Composing.Current;
using FileSystems = Umbraco.Core.IO.FileSystems;
using Umbraco.Web.Templates;

namespace Umbraco.Tests.Testing
{
Expand Down Expand Up @@ -230,6 +231,10 @@ protected virtual void ComposeWeb()
.Append<TranslationSection>();
Composition.RegisterUnique<ISectionService, SectionService>();

Composition.RegisterUnique<HtmlLocalLinkParser>();
Composition.RegisterUnique<HtmlUrlParser>();
Composition.RegisterUnique<HtmlImageSourceParser>();

}

protected virtual void ComposeMisc()
Expand Down
Loading

0 comments on commit 9980904

Please sign in to comment.