* Update to dotnet 9 and update nuget packages * Update umbraco code version * Update Directory.Build.props Co-authored-by: Elitsa Marinovska <21998037+elit0451@users.noreply.github.com> * Include preview version in pipeline * update template projects * update global json with specific version * Update version.json to v15 * Rename TrimStart and TrimEnd to string specific * Rename to Exact * Update global.json Co-authored-by: Ronald Barendse <ronald@barend.se> * Remove includePreviewVersion * Rename to trim exact * Add new Hybridcache project * Add tests * Start implementing PublishedContent.cs * Implement repository for content * Refactor to use async everywhere * Add cache refresher * make public as needed for serialization * Use content type cache to get content type out * Refactor to use ContentCacheNode model, that goes in the memory cache * Remove content node kit as its not needed * Implement tests for ensuring caching * Implement better asserts * Implement published property * Refactor to use mapping * Rename to document tests * Update to test properties * Create more tests * Refactor mock tests into own file * Update property test * Fix published version of content * Change default cache level to elements * Refactor to always have draft * Refactor to not use PublishedModelFactory * Added tests * Added and updated tests * Fixed tests * Don't return empty object with id * More tests * Added key * Another key * Refactor CacheService to be responsible for using the hybrid cache * Use notification handler to remove deleted content from cache * Add more tests for missing functions * Implement missing methods * Remove HasContent as it pertains to routing * Fik up test * formatting * refactor variable names * Implement variant tests * Map all the published content properties * Get item out of cache first, to assert updated * Implement member cache * Add member test * Implement media cache * Implement property tests for media tests * Refactor tests to use extension method * Add more media tests * Refactor properties to no longer have element caching * Don't use property cache level * Start implementing seeding * Only seed when main * Add Immutable for performance * Implement permanent seeding of content * Implement cache settings * Implement tests for seeding * Update package version * start refactoring nurepo * Refactor so draft & published nodes are cached individually * Refactor RefreshContent to take node instead of IContent * Refactor media to also use cache nodes * Remove member from repo as it isn't cached * Refactor media to not include preview, as media has no draft * create new benchmark project * POC Integration benchmarks with custom api controllers * Start implementing content picker tests * Implement domain cache * Rework content cache to implement interface * Start implementing elements cache * Implement published snapshot service * Publish snapshot tests * Use snapshot for elements cache * Create test proving we don't clear cache when updating content picker * Clear entire elements cache * Remove properties from element cache, when content gets updated. * Rename methods to async * Refactor to use old cache interfaces instead of new ones * Remove snapshot, as it is no longer needed * Fix tests building * Refactor domaincache to not have snapshots * Delete benchmarks * Delete benchmarks * Add HybridCacheProject to Umbraco * Add comment to route value transformer * Implement is draft * remove snapshot from property * V15 updated the hybrid caching integration tests to use ContentEditingService (#16947) * Added builder extension withParentKey * Created builder with ContentEditingService * Added usage of the ContentEditingService to SETUP * Started using ContentEditingService builder in tests * Updated builder extensions * Fixed builder * Clean up * Clean up, not done * Added Ids * Remove entries from cache on delete * Fix up seeding logic * Don't register hybrid cache twice * Change seeded entry options * Update hybrid cache package * Fix up published property to work with delivery api again * Fix dependency injection to work with tests * Fix naming * Dont make caches nullable * Make content node sealed * Remove path and other unused from content node * Remove hacky 2 phase ctor * Refactor to actually set content templates * Remove umbraco context * Remove "HasBy" methods * rename property data * Delete obsolete legacy stuff * Add todo for making expiration configurable * Add todo in UmbracoContext * Add clarifying comment in content factory * Remove xml stuff from published property * Fix according to review * Make content type cache injectible * Make content type cache injectible * Rename to database cache repository * Rename to document cache * Add TODO * Refactor to async * Rename to async * Make everything async * Remove duplicate line from json schema * Move Hybrid cache project * Remove leftover file * Refactor to use keys * Refactor published content to no longer have content data, as it is on the node itself * Refactor to member to use proper content node ctor * Move tests to own folder * Add immutable objects to property and content data for performance * Make property data public * Fix member caching to be singleton * Obsolete GetContentType * Remove todo * Fix naming * Fix lots of exposed errors due to scope test * Add final scope tests * Rename to document cache service * Rename test files * Create new doc type tests * Add ignore to tests * Start implementing refresh for content type save * Clear contenttype cache when contenttype is updated * Fix test Teh contenttype is not upated unless the property is dirty * Use init for ContentSourceDto * Fix get by key in PublishedContentTypeCache * Remove ContentType from PublishedContentTypeCache when contenttype is deleted * Update to preview 7 * Fix versions * Increase timeout for sqlite integration tests * Undo timeout increase * Try and undo init change to ContentSourceDto * That wasn't it chief * Try and make DomainAndUrlsTests non NonParallelizable * Update versions * Only run cache tests on linux for now --------- Co-authored-by: Elitsa Marinovska <21998037+elit0451@users.noreply.github.com> Co-authored-by: Ronald Barendse <ronald@barend.se> Co-authored-by: Andreas Zerbst <andr317c@live.dk> Co-authored-by: Sven Geusens <sge@umbraco.dk> Co-authored-by: Andreas Zerbst <73799582+andr317c@users.noreply.github.com> Co-authored-by: nikolajlauridsen <nikolajlauridsen@protonmail.ch>
460 lines
24 KiB
C#
460 lines
24 KiB
C#
using Moq;
|
|
using NUnit.Framework;
|
|
using Umbraco.Cms.Core;
|
|
using Umbraco.Cms.Core.DeliveryApi;
|
|
using Umbraco.Cms.Core.Models.DeliveryApi;
|
|
using Umbraco.Cms.Core.Models.PublishedContent;
|
|
using Umbraco.Cms.Core.PropertyEditors;
|
|
using Umbraco.Cms.Core.PropertyEditors.DeliveryApi;
|
|
using Umbraco.Cms.Core.PropertyEditors.ValueConverters;
|
|
using Umbraco.Cms.Core.PublishedCache;
|
|
using Umbraco.Cms.Infrastructure.DeliveryApi;
|
|
using Umbraco.Cms.Infrastructure.Serialization;
|
|
|
|
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.DeliveryApi;
|
|
|
|
/// <summary>
|
|
/// The tests contained within this class all serve to test property expansion V1 and V2 exactly the same.
|
|
/// </summary>
|
|
public abstract class OutputExpansionStrategyTestBase : PropertyValueConverterTests
|
|
{
|
|
private IPublishedContentType _contentType;
|
|
private IPublishedContentType _elementType;
|
|
private IPublishedContentType _mediaType;
|
|
|
|
[SetUp]
|
|
public void SetUp()
|
|
{
|
|
var contentType = new Mock<IPublishedContentType>();
|
|
contentType.SetupGet(c => c.Alias).Returns("thePageType");
|
|
contentType.SetupGet(c => c.ItemType).Returns(PublishedItemType.Content);
|
|
_contentType = contentType.Object;
|
|
var elementType = new Mock<IPublishedContentType>();
|
|
elementType.SetupGet(c => c.Alias).Returns("theElementType");
|
|
elementType.SetupGet(c => c.ItemType).Returns(PublishedItemType.Element);
|
|
_elementType = elementType.Object;
|
|
var mediaType = new Mock<IPublishedContentType>();
|
|
mediaType.SetupGet(c => c.Alias).Returns("theMediaType");
|
|
mediaType.SetupGet(c => c.ItemType).Returns(PublishedItemType.Media);
|
|
_mediaType = mediaType.Object;
|
|
}
|
|
|
|
[Test]
|
|
public void OutputExpansionStrategy_ExpandsNothingByDefault()
|
|
{
|
|
var accessor = CreateOutputExpansionStrategyAccessor(false);
|
|
var apiContentBuilder = new ApiContentBuilder(new ApiContentNameProvider(), ApiContentRouteBuilder(), accessor);
|
|
|
|
var content = new Mock<IPublishedContent>();
|
|
var prop1 = new PublishedElementPropertyBase(DeliveryApiPropertyType, content.Object, false, PropertyCacheLevel.None);
|
|
var prop2 = new PublishedElementPropertyBase(DefaultPropertyType, content.Object, false, PropertyCacheLevel.None);
|
|
|
|
var contentPickerContent = CreateSimplePickedContent(123, 456);
|
|
var contentPickerProperty = CreateContentPickerProperty(content.Object, contentPickerContent.Key, "contentPicker", apiContentBuilder);
|
|
|
|
SetupContentMock(content, prop1, prop2, contentPickerProperty);
|
|
|
|
var result = apiContentBuilder.Build(content.Object);
|
|
|
|
Assert.AreEqual(3, result.Properties.Count);
|
|
Assert.AreEqual("Delivery API value", result.Properties[DeliveryApiPropertyType.Alias]);
|
|
Assert.AreEqual("Default value", result.Properties[DefaultPropertyType.Alias]);
|
|
var contentPickerOutput = result.Properties["contentPicker"] as ApiContent;
|
|
Assert.IsNotNull(contentPickerOutput);
|
|
Assert.AreEqual(contentPickerContent.Key, contentPickerOutput.Id);
|
|
Assert.IsEmpty(contentPickerOutput.Properties);
|
|
}
|
|
|
|
[Test]
|
|
public void OutputExpansionStrategy_CanExpandSpecificContent()
|
|
{
|
|
var accessor = CreateOutputExpansionStrategyAccessor(false, new[] { "contentPickerTwo" });
|
|
var apiContentBuilder = new ApiContentBuilder(new ApiContentNameProvider(), ApiContentRouteBuilder(), accessor);
|
|
|
|
var content = new Mock<IPublishedContent>();
|
|
|
|
var contentPickerOneContent = CreateSimplePickedContent(12, 34);
|
|
var contentPickerOneProperty = CreateContentPickerProperty(content.Object, contentPickerOneContent.Key, "contentPickerOne", apiContentBuilder);
|
|
var contentPickerTwoContent = CreateSimplePickedContent(56, 78);
|
|
var contentPickerTwoProperty = CreateContentPickerProperty(content.Object, contentPickerTwoContent.Key, "contentPickerTwo", apiContentBuilder);
|
|
|
|
SetupContentMock(content, contentPickerOneProperty, contentPickerTwoProperty);
|
|
|
|
var result = apiContentBuilder.Build(content.Object);
|
|
|
|
Assert.AreEqual(2, result.Properties.Count);
|
|
|
|
var contentPickerOneOutput = result.Properties["contentPickerOne"] as ApiContent;
|
|
Assert.IsNotNull(contentPickerOneOutput);
|
|
Assert.AreEqual(contentPickerOneContent.Key, contentPickerOneOutput.Id);
|
|
Assert.IsEmpty(contentPickerOneOutput.Properties);
|
|
|
|
var contentPickerTwoOutput = result.Properties["contentPickerTwo"] as ApiContent;
|
|
Assert.IsNotNull(contentPickerTwoOutput);
|
|
Assert.AreEqual(contentPickerTwoContent.Key, contentPickerTwoOutput.Id);
|
|
Assert.AreEqual(2, contentPickerTwoOutput.Properties.Count);
|
|
Assert.AreEqual(56, contentPickerTwoOutput.Properties["numberOne"]);
|
|
Assert.AreEqual(78, contentPickerTwoOutput.Properties["numberTwo"]);
|
|
}
|
|
|
|
[TestCase(false)]
|
|
[TestCase(true)]
|
|
public void OutputExpansionStrategy_CanExpandSpecificMedia(bool mediaPicker3)
|
|
{
|
|
var accessor = CreateOutputExpansionStrategyAccessor(false, new[] { "mediaPickerTwo" });
|
|
var apiMediaBuilder = new ApiMediaBuilder(
|
|
new ApiContentNameProvider(),
|
|
new ApiMediaUrlProvider(PublishedUrlProvider),
|
|
Mock.Of<IPublishedValueFallback>(),
|
|
accessor);
|
|
|
|
var media = new Mock<IPublishedContent>();
|
|
|
|
var mediaPickerOneContent = CreateSimplePickedMedia(12, 34);
|
|
var mediaPickerOneProperty = mediaPicker3
|
|
? CreateMediaPicker3Property(media.Object, mediaPickerOneContent.Key, "mediaPickerOne", apiMediaBuilder)
|
|
: CreateMediaPickerProperty(media.Object, mediaPickerOneContent.Key, "mediaPickerOne", apiMediaBuilder);
|
|
var mediaPickerTwoContent = CreateSimplePickedMedia(56, 78);
|
|
var mediaPickerTwoProperty = mediaPicker3
|
|
? CreateMediaPicker3Property(media.Object, mediaPickerTwoContent.Key, "mediaPickerTwo", apiMediaBuilder)
|
|
: CreateMediaPickerProperty(media.Object, mediaPickerTwoContent.Key, "mediaPickerTwo", apiMediaBuilder);
|
|
|
|
SetupMediaMock(media, mediaPickerOneProperty, mediaPickerTwoProperty);
|
|
|
|
var result = apiMediaBuilder.Build(media.Object);
|
|
|
|
Assert.AreEqual(2, result.Properties.Count);
|
|
|
|
var mediaPickerOneOutput = (result.Properties["mediaPickerOne"] as IEnumerable<IApiMedia>)?.FirstOrDefault();
|
|
Assert.IsNotNull(mediaPickerOneOutput);
|
|
Assert.AreEqual(mediaPickerOneContent.Key, mediaPickerOneOutput.Id);
|
|
Assert.IsEmpty(mediaPickerOneOutput.Properties);
|
|
|
|
var mediaPickerTwoOutput = (result.Properties["mediaPickerTwo"] as IEnumerable<IApiMedia>)?.FirstOrDefault();
|
|
Assert.IsNotNull(mediaPickerTwoOutput);
|
|
Assert.AreEqual(mediaPickerTwoContent.Key, mediaPickerTwoOutput.Id);
|
|
Assert.AreEqual(2, mediaPickerTwoOutput.Properties.Count);
|
|
Assert.AreEqual(56, mediaPickerTwoOutput.Properties["numberOne"]);
|
|
Assert.AreEqual(78, mediaPickerTwoOutput.Properties["numberTwo"]);
|
|
}
|
|
|
|
[Test]
|
|
public void OutputExpansionStrategy_CanExpandAllContent()
|
|
{
|
|
var accessor = CreateOutputExpansionStrategyAccessor(true);
|
|
var apiContentBuilder = new ApiContentBuilder(new ApiContentNameProvider(), ApiContentRouteBuilder(), accessor);
|
|
|
|
var content = new Mock<IPublishedContent>();
|
|
|
|
var contentPickerOneContent = CreateSimplePickedContent(12, 34);
|
|
var contentPickerOneProperty = CreateContentPickerProperty(content.Object, contentPickerOneContent.Key, "contentPickerOne", apiContentBuilder);
|
|
var contentPickerTwoContent = CreateSimplePickedContent(56, 78);
|
|
var contentPickerTwoProperty = CreateContentPickerProperty(content.Object, contentPickerTwoContent.Key, "contentPickerTwo", apiContentBuilder);
|
|
|
|
SetupContentMock(content, contentPickerOneProperty, contentPickerTwoProperty);
|
|
|
|
var result = apiContentBuilder.Build(content.Object);
|
|
|
|
Assert.AreEqual(2, result.Properties.Count);
|
|
|
|
var contentPickerOneOutput = result.Properties["contentPickerOne"] as ApiContent;
|
|
Assert.IsNotNull(contentPickerOneOutput);
|
|
Assert.AreEqual(contentPickerOneContent.Key, contentPickerOneOutput.Id);
|
|
Assert.AreEqual(2, contentPickerOneOutput.Properties.Count);
|
|
Assert.AreEqual(12, contentPickerOneOutput.Properties["numberOne"]);
|
|
Assert.AreEqual(34, contentPickerOneOutput.Properties["numberTwo"]);
|
|
|
|
var contentPickerTwoOutput = result.Properties["contentPickerTwo"] as ApiContent;
|
|
Assert.IsNotNull(contentPickerTwoOutput);
|
|
Assert.AreEqual(contentPickerTwoContent.Key, contentPickerTwoOutput.Id);
|
|
Assert.AreEqual(2, contentPickerTwoOutput.Properties.Count);
|
|
Assert.AreEqual(56, contentPickerTwoOutput.Properties["numberOne"]);
|
|
Assert.AreEqual(78, contentPickerTwoOutput.Properties["numberTwo"]);
|
|
}
|
|
|
|
[TestCase("contentPicker", "contentPicker")]
|
|
[TestCase("rootPicker", "nestedPicker")]
|
|
public void OutputExpansionStrategy_DoesNotExpandNestedContentPicker(string rootPropertyTypeAlias, string nestedPropertyTypeAlias)
|
|
{
|
|
var accessor = CreateOutputExpansionStrategyAccessor(false, new[] { rootPropertyTypeAlias, nestedPropertyTypeAlias });
|
|
var apiContentBuilder = new ApiContentBuilder(new ApiContentNameProvider(), ApiContentRouteBuilder(), accessor);
|
|
|
|
var content = new Mock<IPublishedContent>();
|
|
|
|
var nestedContentPickerContent = CreateSimplePickedContent(987, 654);
|
|
var contentPickerContent = CreateMultiLevelPickedContent(123, nestedContentPickerContent, nestedPropertyTypeAlias, apiContentBuilder);
|
|
var contentPickerContentProperty = CreateContentPickerProperty(content.Object, contentPickerContent.Key, rootPropertyTypeAlias, apiContentBuilder);
|
|
|
|
SetupContentMock(content, contentPickerContentProperty);
|
|
|
|
var result = apiContentBuilder.Build(content.Object);
|
|
|
|
Assert.AreEqual(1, result.Properties.Count);
|
|
|
|
var contentPickerOneOutput = result.Properties[rootPropertyTypeAlias] as ApiContent;
|
|
Assert.IsNotNull(contentPickerOneOutput);
|
|
Assert.AreEqual(contentPickerContent.Key, contentPickerOneOutput.Id);
|
|
Assert.AreEqual(2, contentPickerOneOutput.Properties.Count);
|
|
Assert.AreEqual(123, contentPickerOneOutput.Properties["number"]);
|
|
|
|
var nestedContentPickerOutput = contentPickerOneOutput.Properties[nestedPropertyTypeAlias] as ApiContent;
|
|
Assert.IsNotNull(nestedContentPickerOutput);
|
|
Assert.AreEqual(nestedContentPickerContent.Key, nestedContentPickerOutput.Id);
|
|
Assert.IsEmpty(nestedContentPickerOutput.Properties);
|
|
}
|
|
|
|
[Test]
|
|
public void OutputExpansionStrategy_DoesNotExpandElementsByDefault()
|
|
{
|
|
var accessor = CreateOutputExpansionStrategyAccessor(false);
|
|
var apiContentBuilder = new ApiContentBuilder(new ApiContentNameProvider(), ApiContentRouteBuilder(), accessor);
|
|
var apiElementBuilder = new ApiElementBuilder(accessor);
|
|
|
|
var contentPickerValue = CreateSimplePickedContent(111, 222);
|
|
var contentPicker2Value = CreateSimplePickedContent(666, 777);
|
|
|
|
var content = new Mock<IPublishedContent>();
|
|
SetupContentMock(
|
|
content,
|
|
CreateNumberProperty(content.Object, 444, "number"),
|
|
CreateElementProperty(content.Object, "element", 333, contentPickerValue.Key, "contentPicker", apiContentBuilder, apiElementBuilder),
|
|
CreateElementProperty(content.Object, "element2", 555, contentPicker2Value.Key, "contentPicker", apiContentBuilder, apiElementBuilder));
|
|
|
|
var result = apiContentBuilder.Build(content.Object);
|
|
|
|
Assert.AreEqual(3, result.Properties.Count);
|
|
Assert.AreEqual(444, result.Properties["number"]);
|
|
|
|
var expectedElementOutputs = new[]
|
|
{
|
|
new
|
|
{
|
|
PropertyAlias = "element",
|
|
ElementNumber = 333,
|
|
ElementContentPicker = contentPickerValue.Key
|
|
},
|
|
new
|
|
{
|
|
PropertyAlias = "element2",
|
|
ElementNumber = 555,
|
|
ElementContentPicker = contentPicker2Value.Key
|
|
}
|
|
};
|
|
|
|
foreach (var expectedElementOutput in expectedElementOutputs)
|
|
{
|
|
var elementOutput = result.Properties[expectedElementOutput.PropertyAlias] as IApiElement;
|
|
Assert.IsNotNull(elementOutput);
|
|
Assert.AreEqual(2, elementOutput.Properties.Count);
|
|
Assert.AreEqual(expectedElementOutput.ElementNumber, elementOutput.Properties["number"]);
|
|
var contentPickerOutput = elementOutput.Properties["contentPicker"] as IApiContent;
|
|
Assert.IsNotNull(contentPickerOutput);
|
|
Assert.AreEqual(expectedElementOutput.ElementContentPicker, contentPickerOutput.Id);
|
|
Assert.AreEqual(0, contentPickerOutput.Properties.Count);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void OutputExpansionStrategy_MappingContent_ThrowsOnInvalidItemType()
|
|
{
|
|
var accessor = CreateOutputExpansionStrategyAccessor(false);
|
|
if (accessor.TryGetValue(out IOutputExpansionStrategy outputExpansionStrategy) is false)
|
|
{
|
|
Assert.Fail("Could not obtain the output expansion strategy");
|
|
}
|
|
|
|
Assert.Throws<ArgumentException>(() => outputExpansionStrategy.MapContentProperties(PublishedMedia));
|
|
}
|
|
|
|
[Test]
|
|
public void OutputExpansionStrategy_MappingMedia_ThrowsOnInvalidItemType()
|
|
{
|
|
var accessor = CreateOutputExpansionStrategyAccessor(false);
|
|
if (accessor.TryGetValue(out IOutputExpansionStrategy outputExpansionStrategy) is false)
|
|
{
|
|
Assert.Fail("Could not obtain the output expansion strategy");
|
|
}
|
|
|
|
Assert.Throws<ArgumentException>(() => outputExpansionStrategy.MapMediaProperties(PublishedContent));
|
|
}
|
|
|
|
[TestCase(true)]
|
|
[TestCase(false)]
|
|
public void OutputExpansionStrategy_ForwardsExpansionStateToPropertyValueConverter(bool expanding)
|
|
{
|
|
var accessor = CreateOutputExpansionStrategyAccessor(false, new[] { expanding ? "theAlias" : "noSuchAlias" });
|
|
var apiContentBuilder = new ApiContentBuilder(new ApiContentNameProvider(), ApiContentRouteBuilder(), accessor);
|
|
|
|
var content = new Mock<IPublishedContent>();
|
|
|
|
var valueConverterMock = new Mock<IDeliveryApiPropertyValueConverter>();
|
|
valueConverterMock.Setup(v => v.IsConverter(It.IsAny<IPublishedPropertyType>())).Returns(true);
|
|
valueConverterMock.Setup(p => p.IsValue(It.IsAny<object?>(), It.IsAny<PropertyValueLevel>())).Returns(true);
|
|
valueConverterMock.Setup(v => v.GetPropertyCacheLevel(It.IsAny<IPublishedPropertyType>())).Returns(PropertyCacheLevel.None);
|
|
valueConverterMock.Setup(v => v.GetDeliveryApiPropertyCacheLevel(It.IsAny<IPublishedPropertyType>())).Returns(PropertyCacheLevel.None);
|
|
valueConverterMock.Setup(v => v.GetDeliveryApiPropertyCacheLevelForExpansion(It.IsAny<IPublishedPropertyType>())).Returns(PropertyCacheLevel.None);
|
|
valueConverterMock.Setup(v => v.ConvertIntermediateToDeliveryApiObject(
|
|
It.IsAny<IPublishedElement>(),
|
|
It.IsAny<IPublishedPropertyType>(),
|
|
It.IsAny<PropertyCacheLevel>(),
|
|
It.IsAny<object?>(),
|
|
It.IsAny<bool>(),
|
|
It.IsAny<bool>()))
|
|
.Returns(expanding ? "Expanding" : "Not expanding");
|
|
|
|
var propertyType = SetupPublishedPropertyType(valueConverterMock.Object, "theAlias", Constants.PropertyEditors.Aliases.Label);
|
|
var property = new PublishedElementPropertyBase(propertyType, content.Object, false, PropertyCacheLevel.None, "The Value");
|
|
|
|
SetupContentMock(content, property);
|
|
|
|
var result = apiContentBuilder.Build(content.Object);
|
|
|
|
Assert.AreEqual(1, result.Properties.Count);
|
|
Assert.AreEqual(expanding ? "Expanding" : "Not expanding", result.Properties["theAlias"] as string);
|
|
}
|
|
|
|
protected abstract IOutputExpansionStrategyAccessor CreateOutputExpansionStrategyAccessor(string? expand = null, string? fields = null);
|
|
|
|
protected IOutputExpansionStrategyAccessor CreateOutputExpansionStrategyAccessor(bool expandAll = false, string[]? expandPropertyAliases = null)
|
|
=> CreateOutputExpansionStrategyAccessor(FormatExpandSyntax(expandAll, expandPropertyAliases));
|
|
|
|
protected abstract string? FormatExpandSyntax(bool expandAll = false, string[]? expandPropertyAliases = null);
|
|
|
|
protected void SetupContentMock(Mock<IPublishedContent> content, params IPublishedProperty[] properties)
|
|
{
|
|
var key = Guid.NewGuid();
|
|
var name = "The page";
|
|
var urlSegment = "url-segment";
|
|
ConfigurePublishedContentMock(content, key, name, urlSegment, _contentType, properties);
|
|
|
|
RegisterContentWithProviders(content.Object);
|
|
}
|
|
|
|
protected void SetupMediaMock(Mock<IPublishedContent> media, params IPublishedProperty[] properties)
|
|
{
|
|
var key = Guid.NewGuid();
|
|
var name = "The media";
|
|
var urlSegment = "media-url-segment";
|
|
ConfigurePublishedContentMock(media, key, name, urlSegment, _mediaType, properties);
|
|
|
|
RegisterMediaWithProviders(media.Object);
|
|
}
|
|
|
|
protected IPublishedContent CreateSimplePickedContent(int numberOneValue, int numberTwoValue)
|
|
{
|
|
var content = new Mock<IPublishedContent>();
|
|
SetupContentMock(
|
|
content,
|
|
CreateNumberProperty(content.Object, numberOneValue, "numberOne"),
|
|
CreateNumberProperty(content.Object, numberTwoValue, "numberTwo"));
|
|
|
|
return content.Object;
|
|
}
|
|
|
|
protected IPublishedContent CreateSimplePickedMedia(int numberOneValue, int numberTwoValue)
|
|
{
|
|
var media = new Mock<IPublishedContent>();
|
|
SetupMediaMock(
|
|
media,
|
|
CreateNumberProperty(media.Object, numberOneValue, "numberOne"),
|
|
CreateNumberProperty(media.Object, numberTwoValue, "numberTwo"));
|
|
|
|
return media.Object;
|
|
}
|
|
|
|
protected IPublishedContent CreateMultiLevelPickedContent(int numberValue, IPublishedContent nestedContentPickerValue, string nestedContentPickerPropertyTypeAlias, ApiContentBuilder apiContentBuilder)
|
|
{
|
|
var content = new Mock<IPublishedContent>();
|
|
SetupContentMock(
|
|
content,
|
|
CreateNumberProperty(content.Object, numberValue, "number"),
|
|
CreateContentPickerProperty(content.Object, nestedContentPickerValue.Key, nestedContentPickerPropertyTypeAlias, apiContentBuilder));
|
|
|
|
return content.Object;
|
|
}
|
|
|
|
internal PublishedElementPropertyBase CreateContentPickerProperty(IPublishedElement parent, Guid pickedContentKey, string propertyTypeAlias, IApiContentBuilder contentBuilder)
|
|
{
|
|
ContentPickerValueConverter contentPickerValueConverter = new ContentPickerValueConverter(PublishedContentCacheMock.Object, contentBuilder);
|
|
var contentPickerPropertyType = SetupPublishedPropertyType(contentPickerValueConverter, propertyTypeAlias, Constants.PropertyEditors.Aliases.ContentPicker);
|
|
|
|
return new PublishedElementPropertyBase(contentPickerPropertyType, parent, false, PropertyCacheLevel.None, new GuidUdi(Constants.UdiEntityType.Document, pickedContentKey).ToString());
|
|
}
|
|
|
|
internal PublishedElementPropertyBase CreateMediaPickerProperty(IPublishedElement parent, Guid pickedMediaKey, string propertyTypeAlias, IApiMediaBuilder mediaBuilder)
|
|
{
|
|
var publishedValueFallback = Mock.Of<IPublishedValueFallback>();
|
|
var apiMediaWithCropsBuilder = new ApiMediaWithCropsBuilder(mediaBuilder, publishedValueFallback);
|
|
|
|
MediaPickerWithCropsValueConverter mediaPickerValueConverter = new MediaPickerWithCropsValueConverter(PublishedSnapshotAccessor, PublishedUrlProvider, publishedValueFallback, new SystemTextJsonSerializer(), apiMediaWithCropsBuilder);
|
|
var mediaPickerPropertyType = SetupPublishedPropertyType(mediaPickerValueConverter, propertyTypeAlias, Constants.PropertyEditors.Aliases.MediaPicker3, new MediaPicker3Configuration());
|
|
|
|
return new PublishedElementPropertyBase(mediaPickerPropertyType, parent, false, PropertyCacheLevel.None, new GuidUdi(Constants.UdiEntityType.Media, pickedMediaKey).ToString());
|
|
}
|
|
|
|
internal PublishedElementPropertyBase CreateMediaPicker3Property(IPublishedElement parent, Guid pickedMediaKey, string propertyTypeAlias, IApiMediaBuilder mediaBuilder)
|
|
{
|
|
var serializer = new SystemTextJsonSerializer();
|
|
var value = serializer.Serialize(new[]
|
|
{
|
|
new MediaPicker3PropertyEditor.MediaPicker3PropertyValueEditor.MediaWithCropsDto
|
|
{
|
|
MediaKey = pickedMediaKey
|
|
}
|
|
});
|
|
|
|
var publishedValueFallback = Mock.Of<IPublishedValueFallback>();
|
|
var apiMediaWithCropsBuilder = new ApiMediaWithCropsBuilder(mediaBuilder, publishedValueFallback);
|
|
|
|
MediaPickerWithCropsValueConverter mediaPickerValueConverter = new MediaPickerWithCropsValueConverter(PublishedSnapshotAccessor, PublishedUrlProvider, publishedValueFallback, new SystemTextJsonSerializer(), apiMediaWithCropsBuilder);
|
|
var mediaPickerPropertyType = SetupPublishedPropertyType(mediaPickerValueConverter, propertyTypeAlias, Constants.PropertyEditors.Aliases.MediaPicker3, new MediaPicker3Configuration());
|
|
|
|
return new PublishedElementPropertyBase(mediaPickerPropertyType, parent, false, PropertyCacheLevel.None, value);
|
|
}
|
|
|
|
internal PublishedElementPropertyBase CreateNumberProperty(IPublishedElement parent, int propertyValue, string propertyTypeAlias)
|
|
{
|
|
var numberPropertyType = SetupPublishedPropertyType(new IntegerValueConverter(), propertyTypeAlias, Constants.PropertyEditors.Aliases.Label);
|
|
return new PublishedElementPropertyBase(numberPropertyType, parent, false, PropertyCacheLevel.None, propertyValue);
|
|
}
|
|
|
|
internal PublishedElementPropertyBase CreateElementProperty(
|
|
IPublishedElement parent,
|
|
string elementPropertyAlias,
|
|
int numberPropertyValue,
|
|
Guid contentPickerPropertyValue,
|
|
string contentPickerPropertyTypeAlias,
|
|
IApiContentBuilder apiContentBuilder,
|
|
IApiElementBuilder apiElementBuilder)
|
|
{
|
|
var element = new Mock<IPublishedElement>();
|
|
element.SetupGet(c => c.ContentType).Returns(_elementType);
|
|
element.SetupGet(c => c.Properties).Returns(new[]
|
|
{
|
|
CreateNumberProperty(element.Object, numberPropertyValue, "number"),
|
|
CreateContentPickerProperty(element.Object, contentPickerPropertyValue, contentPickerPropertyTypeAlias, apiContentBuilder)
|
|
});
|
|
|
|
var elementValueConverter = new Mock<IDeliveryApiPropertyValueConverter>();
|
|
elementValueConverter
|
|
.Setup(p => p.ConvertIntermediateToDeliveryApiObject(
|
|
It.IsAny<IPublishedElement>(),
|
|
It.IsAny<IPublishedPropertyType>(),
|
|
It.IsAny<PropertyCacheLevel>(),
|
|
It.IsAny<object?>(),
|
|
It.IsAny<bool>(),
|
|
It.IsAny<bool>()))
|
|
.Returns(() => apiElementBuilder.Build(element.Object));
|
|
elementValueConverter.Setup(p => p.IsConverter(It.IsAny<IPublishedPropertyType>())).Returns(true);
|
|
elementValueConverter.Setup(p => p.IsValue(It.IsAny<object?>(), It.IsAny<PropertyValueLevel>())).Returns(true);
|
|
elementValueConverter.Setup(p => p.GetPropertyCacheLevel(It.IsAny<IPublishedPropertyType>())).Returns(PropertyCacheLevel.None);
|
|
elementValueConverter.Setup(p => p.GetDeliveryApiPropertyCacheLevel(It.IsAny<IPublishedPropertyType>())).Returns(PropertyCacheLevel.None);
|
|
elementValueConverter.Setup(p => p.GetDeliveryApiPropertyCacheLevelForExpansion(It.IsAny<IPublishedPropertyType>())).Returns(PropertyCacheLevel.None);
|
|
|
|
var elementPropertyType = SetupPublishedPropertyType(elementValueConverter.Object, elementPropertyAlias, "My.Element.Property");
|
|
return new PublishedElementPropertyBase(elementPropertyType, parent, false, PropertyCacheLevel.None);
|
|
}
|
|
|
|
protected IApiContentRouteBuilder ApiContentRouteBuilder() => CreateContentRouteBuilder(ApiContentPathProvider, CreateGlobalSettings());
|
|
}
|