V15 QA Hybrid Cache added media cache tests and fixed media cache refreshing (#17160)
* 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 * Updated tests * Added tests * Use init for ContentSourceDto * Startup of setup * Fix get by key in PublishedContentTypeCache * Remove ContentType from PublishedContentTypeCache when contenttype is deleted * Created interfaces for the builder with the necessary properties * Created builder for PropertyTypeContainer * Created builder for PropertyTypeEditing * Created builder for PropertyTypeValidationEditing * Made adjustments to the builder * Updated name of usage * Commented out to test * Cleaned up builders * Updated integration test setup * Moved tests * Added interface * Add IDocumentSeedKeyProvider and migrate existing logic to seed key provider * Added functionality to the INavigationQueryService to get root keys * Fixed issue with navigation * Created helper to Convert a IContentType to ContentTypeUpdateModel * Added interfaces * Added builder * Cleaned up builders and added fixes * Added tests for PublishedContentTypeCache * Applied changes in builder * Add BreadthFirstKeyProvider * Use ISet for seedkey providers * Implement GetContentSource by key * Seed the cache with keys provided by seed key providers * Builder updates * Test setup updates * Updated tests * Dont require contenttype keys for seeding * Fix cache settings * Don't inject cache settings into SeedingNotificationHandler * Fix tests * Use enlistment for setting updated cache item * Pin seeded nodes for longer * Fix BreadthFirstKeyProvider * Fix ContentTypeSeedKeyProvider * Fix tests * Only seed published documents * Only cache published if contentCacheNode is not draft * Fix incorrect templateId * Removed unnecessary setup * initialized value * Fixed template test * Removed test * Updated tests * Removed code that was not used * Removed unused cacheSettings * Re-organize to support media cache seeding * Add MediaBreadthFirstKeyProvider * Seed media * Don't use IdKeyMap when removing content from cache * Don't clear IdKeyMap in DocumentCacheService * Add unit tests * Don't use IdKeyMap when deleting media * Add default value to timespan * Use cancellation tokens when doing loop * Fixed Models Builder error * Builder testing * Media test * Created builders * Updated method from getByKey to getById to maintain structure * Updated test setup * Moved tests * Cleaned up builders * Added helper * Added space * Updated tests * Cleaned setup * Added tests for MediaTypes * Uncommented tests * Added builder extensions * Added interfaces for builder methods * Updated to use interface pattern * Updated name * Used builder * Cleaned up test * Added media scope tests * Removed PropertyTypeModelBuilder * moved PropertyTypeModelBuilder to PropertyTypeEditingBuilder * Removed constructor * Removed duplicate * Fixed naming * Reverted * Removed space * Added todos * Removed only run on linux * Commet out DocumentHybridCacheTemplateTest again This is fixed in the release branch * Update media when media type is updated * Remove todo the tests pass now --------- Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com> Co-authored-by: Zeegaan <skrivdetud@gmail.com> Co-authored-by: Sven Geusens <sge@umbraco.dk> Co-authored-by: nikolajlauridsen <nikolajlauridsen@protonmail.ch> Co-authored-by: Bjarke Berg <mail@bergmania.dk>
This commit is contained in:
@@ -18,5 +18,5 @@ public interface IPublishedMediaCache : IPublishedCache
|
||||
/// <param name="key">The content unique identifier.</param>
|
||||
/// <returns>The content, or null.</returns>
|
||||
/// <remarks>Considers published or unpublished content depending on defaults.</remarks>
|
||||
Task<IPublishedContent?> GetByKeyAsync(Guid key);
|
||||
Task<IPublishedContent?> GetByIdAsync(Guid key);
|
||||
}
|
||||
|
||||
@@ -65,6 +65,8 @@ public static class UmbracoBuilderExtensions
|
||||
builder.AddNotificationAsyncHandler<MediaDeletedNotification, CacheRefreshingNotificationHandler>();
|
||||
builder.AddNotificationAsyncHandler<ContentTypeRefreshedNotification, CacheRefreshingNotificationHandler>();
|
||||
builder.AddNotificationAsyncHandler<ContentTypeDeletedNotification, CacheRefreshingNotificationHandler>();
|
||||
builder.AddNotificationAsyncHandler<MediaTypeRefreshedNotification, CacheRefreshingNotificationHandler>();
|
||||
builder.AddNotificationAsyncHandler<MediaTypeDeletedNotification, CacheRefreshingNotificationHandler>();
|
||||
builder.AddNotificationAsyncHandler<UmbracoApplicationStartedNotification, SeedingNotificationHandler>();
|
||||
builder.AddCacheSeeding();
|
||||
return builder;
|
||||
|
||||
@@ -18,17 +18,17 @@ public class MediaCache : IPublishedMediaCache
|
||||
|
||||
public async Task<IPublishedContent?> GetByIdAsync(int id) => await _mediaCacheService.GetByIdAsync(id);
|
||||
|
||||
public async Task<IPublishedContent?> GetByKeyAsync(Guid key) => await _mediaCacheService.GetByKeyAsync(key);
|
||||
public async Task<IPublishedContent?> GetByIdAsync(Guid key) => await _mediaCacheService.GetByKeyAsync(key);
|
||||
|
||||
public IPublishedContent? GetById(bool preview, int contentId) => GetByIdAsync(contentId).GetAwaiter().GetResult();
|
||||
|
||||
public IPublishedContent? GetById(bool preview, Guid contentId) =>
|
||||
GetByKeyAsync(contentId).GetAwaiter().GetResult();
|
||||
GetByIdAsync(contentId).GetAwaiter().GetResult();
|
||||
|
||||
|
||||
public IPublishedContent? GetById(int contentId) => GetByIdAsync(contentId).GetAwaiter().GetResult();
|
||||
|
||||
public IPublishedContent? GetById(Guid contentId) => GetByKeyAsync(contentId).GetAwaiter().GetResult();
|
||||
public IPublishedContent? GetById(Guid contentId) => GetByIdAsync(contentId).GetAwaiter().GetResult();
|
||||
|
||||
|
||||
public IPublishedContentType? GetContentType(Guid key) => _publishedContentTypeCache.Get(PublishedItemType.Media, key);
|
||||
|
||||
@@ -19,7 +19,9 @@ internal sealed class CacheRefreshingNotificationHandler :
|
||||
INotificationAsyncHandler<MediaRefreshNotification>,
|
||||
INotificationAsyncHandler<MediaDeletedNotification>,
|
||||
INotificationAsyncHandler<ContentTypeRefreshedNotification>,
|
||||
INotificationAsyncHandler<ContentTypeDeletedNotification>
|
||||
INotificationAsyncHandler<ContentTypeDeletedNotification>,
|
||||
INotificationAsyncHandler<MediaTypeRefreshedNotification>,
|
||||
INotificationAsyncHandler<MediaTypeDeletedNotification>
|
||||
{
|
||||
private readonly IDocumentCacheService _documentCacheService;
|
||||
private readonly IMediaCacheService _mediaCacheService;
|
||||
@@ -126,7 +128,7 @@ internal sealed class CacheRefreshingNotificationHandler :
|
||||
var contentTypeIds = notification.Changes.Where(x => x.ChangeTypes.HasTypesAny(types)).Select(x => x.Item.Id)
|
||||
.ToArray();
|
||||
|
||||
if (contentTypeIds.Length != 0)
|
||||
if (contentTypeIds.Length > 0)
|
||||
{
|
||||
foreach (var contentTypeId in contentTypeIds)
|
||||
{
|
||||
@@ -148,4 +150,33 @@ internal sealed class CacheRefreshingNotificationHandler :
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task HandleAsync(MediaTypeRefreshedNotification notification, CancellationToken cancellationToken)
|
||||
{
|
||||
const ContentTypeChangeTypes types // only for those that have been refreshed
|
||||
= ContentTypeChangeTypes.RefreshMain | ContentTypeChangeTypes.RefreshOther;
|
||||
var mediaTypeIds = notification.Changes.Where(x => x.ChangeTypes.HasTypesAny(types)).Select(x => x.Item.Id)
|
||||
.ToArray();
|
||||
|
||||
if (mediaTypeIds.Length > 0)
|
||||
{
|
||||
foreach (var mediaTypeId in mediaTypeIds)
|
||||
{
|
||||
_publishedContentTypeCache.ClearContentType(mediaTypeId);
|
||||
}
|
||||
|
||||
_mediaCacheService.Rebuild(mediaTypeIds);
|
||||
}
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task HandleAsync(MediaTypeDeletedNotification notification, CancellationToken cancellationToken)
|
||||
{
|
||||
foreach (IMediaType deleted in notification.DeletedEntities )
|
||||
{
|
||||
_publishedContentTypeCache.ClearContentType(deleted.Id);
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -237,7 +237,7 @@ AND cmsContentNu.nodeId IS NULL
|
||||
return CreateContentNodeKit(dto, serializer, preview);
|
||||
}
|
||||
|
||||
private IEnumerable<ContentSourceDto> GetContentSourceByDocumentTypeKey(IEnumerable<Guid> documentTypeKeys)
|
||||
private IEnumerable<ContentSourceDto> GetContentSourceByDocumentTypeKey(IEnumerable<Guid> documentTypeKeys, Guid objectType)
|
||||
{
|
||||
Guid[] keys = documentTypeKeys.ToArray();
|
||||
if (keys.Any() is false)
|
||||
@@ -248,19 +248,27 @@ AND cmsContentNu.nodeId IS NULL
|
||||
Sql<ISqlContext>? sql = SqlContentSourcesSelect()
|
||||
.InnerJoin<NodeDto>("n")
|
||||
.On<NodeDto, ContentDto>((n, c) => n.NodeId == c.ContentTypeId, "n", "umbracoContent")
|
||||
.Append(SqlObjectTypeNotTrashed(SqlContext, Constants.ObjectTypes.Document))
|
||||
.Append(SqlObjectTypeNotTrashed(SqlContext, objectType))
|
||||
.WhereIn<NodeDto>(x => x.UniqueId, keys,"n")
|
||||
.Append(SqlOrderByLevelIdSortOrder(SqlContext));
|
||||
|
||||
return GetContentNodeDtos(sql);
|
||||
}
|
||||
|
||||
public IEnumerable<ContentCacheNode> GetContentByContentTypeKey(IEnumerable<Guid> keys)
|
||||
public IEnumerable<ContentCacheNode> GetContentByContentTypeKey(IEnumerable<Guid> keys, ContentCacheDataSerializerEntityType entityType)
|
||||
{
|
||||
IEnumerable<ContentSourceDto> dtos = GetContentSourceByDocumentTypeKey(keys);
|
||||
Guid objectType = entityType switch
|
||||
{
|
||||
ContentCacheDataSerializerEntityType.Document => Constants.ObjectTypes.Document,
|
||||
ContentCacheDataSerializerEntityType.Media => Constants.ObjectTypes.Media,
|
||||
ContentCacheDataSerializerEntityType.Member => Constants.ObjectTypes.Member,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(entityType), entityType, null),
|
||||
};
|
||||
|
||||
IEnumerable<ContentSourceDto> dtos = GetContentSourceByDocumentTypeKey(keys, objectType);
|
||||
|
||||
IContentCacheDataSerializer serializer =
|
||||
_contentCacheDataSerializerFactory.Create(ContentCacheDataSerializerEntityType.Document);
|
||||
_contentCacheDataSerializerFactory.Create(entityType);
|
||||
|
||||
foreach (ContentSourceDto row in dtos)
|
||||
{
|
||||
@@ -269,8 +277,8 @@ AND cmsContentNu.nodeId IS NULL
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<Guid> GetContentKeysByContentTypeKeys(IEnumerable<Guid> keys, bool published = false)
|
||||
=> GetContentSourceByDocumentTypeKey(keys).Where(x => x.Published == published).Select(x => x.Key);
|
||||
public IEnumerable<Guid> GetDocumentKeysByContentTypeKeys(IEnumerable<Guid> keys, bool published = false)
|
||||
=> GetContentSourceByDocumentTypeKey(keys, Constants.ObjectTypes.Document).Where(x => x.Published == published).Select(x => x.Key);
|
||||
|
||||
public async Task<ContentCacheNode?> GetMediaSourceAsync(int id)
|
||||
{
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Infrastructure.HybridCache.Serialization;
|
||||
|
||||
namespace Umbraco.Cms.Infrastructure.HybridCache.Persistence;
|
||||
|
||||
@@ -15,14 +16,14 @@ internal interface IDatabaseCacheRepository
|
||||
Task<ContentCacheNode?> GetMediaSourceAsync(Guid key);
|
||||
|
||||
|
||||
IEnumerable<ContentCacheNode> GetContentByContentTypeKey(IEnumerable<Guid> keys);
|
||||
IEnumerable<ContentCacheNode> GetContentByContentTypeKey(IEnumerable<Guid> keys, ContentCacheDataSerializerEntityType entityType);
|
||||
|
||||
/// <summary>
|
||||
/// Gets all content keys of specific document types
|
||||
/// </summary>
|
||||
/// <param name="keys">The document types to find content using.</param>
|
||||
/// <returns>The keys of all content use specific document types.</returns>
|
||||
IEnumerable<Guid> GetContentKeysByContentTypeKeys(IEnumerable<Guid> keys, bool published = false);
|
||||
IEnumerable<Guid> GetDocumentKeysByContentTypeKeys(IEnumerable<Guid> keys, bool published = false);
|
||||
|
||||
/// <summary>
|
||||
/// Refreshes the nucache database row for the given cache node />
|
||||
|
||||
@@ -24,7 +24,7 @@ internal sealed class ContentTypeSeedKeyProvider : IDocumentSeedKeyProvider
|
||||
public ISet<Guid> GetSeedKeys()
|
||||
{
|
||||
using ICoreScope scope = _scopeProvider.CreateCoreScope();
|
||||
var documentKeys = _databaseCacheRepository.GetContentKeysByContentTypeKeys(_cacheSettings.ContentTypeKeys, published: true).ToHashSet();
|
||||
var documentKeys = _databaseCacheRepository.GetDocumentKeysByContentTypeKeys(_cacheSettings.ContentTypeKeys, published: true).ToHashSet();
|
||||
scope.Complete();
|
||||
|
||||
return documentKeys;
|
||||
|
||||
@@ -7,6 +7,7 @@ using Umbraco.Cms.Core.Scoping;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Infrastructure.HybridCache.Factories;
|
||||
using Umbraco.Cms.Infrastructure.HybridCache.Persistence;
|
||||
using Umbraco.Cms.Infrastructure.HybridCache.Serialization;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Infrastructure.HybridCache.Services;
|
||||
@@ -97,7 +98,7 @@ internal sealed class DocumentCacheService : IDocumentCacheService
|
||||
public IEnumerable<IPublishedContent> GetByContentType(IPublishedContentType contentType)
|
||||
{
|
||||
using ICoreScope scope = _scopeProvider.CreateCoreScope();
|
||||
IEnumerable<ContentCacheNode> nodes = _databaseCacheRepository.GetContentByContentTypeKey([contentType.Key]);
|
||||
IEnumerable<ContentCacheNode> nodes = _databaseCacheRepository.GetContentByContentTypeKey([contentType.Key], ContentCacheDataSerializerEntityType.Document);
|
||||
scope.Complete();
|
||||
|
||||
return nodes
|
||||
@@ -239,11 +240,11 @@ internal sealed class DocumentCacheService : IDocumentCacheService
|
||||
scope.Complete();
|
||||
}
|
||||
|
||||
public void Rebuild(IReadOnlyCollection<int> contentTypeKeys)
|
||||
public void Rebuild(IReadOnlyCollection<int> contentTypeIds)
|
||||
{
|
||||
using ICoreScope scope = _scopeProvider.CreateCoreScope();
|
||||
_databaseCacheRepository.Rebuild(contentTypeKeys.ToList());
|
||||
IEnumerable<ContentCacheNode> contentByContentTypeKey = _databaseCacheRepository.GetContentByContentTypeKey(contentTypeKeys.Select(x => _idKeyMap.GetKeyForId(x, UmbracoObjectTypes.DocumentType).Result));
|
||||
_databaseCacheRepository.Rebuild(contentTypeIds.ToList());
|
||||
IEnumerable<ContentCacheNode> contentByContentTypeKey = _databaseCacheRepository.GetContentByContentTypeKey(contentTypeIds.Select(x => _idKeyMap.GetKeyForId(x, UmbracoObjectTypes.DocumentType).Result), ContentCacheDataSerializerEntityType.Document);
|
||||
|
||||
foreach (ContentCacheNode content in contentByContentTypeKey)
|
||||
{
|
||||
|
||||
@@ -17,7 +17,7 @@ public interface IDocumentCacheService
|
||||
|
||||
Task DeleteItemAsync(IContentBase content);
|
||||
|
||||
void Rebuild(IReadOnlyCollection<int> contentTypeKeys);
|
||||
void Rebuild(IReadOnlyCollection<int> contentTypeIds);
|
||||
|
||||
internal IEnumerable<IPublishedContent> GetByContentType(IPublishedContentType contentType);
|
||||
}
|
||||
|
||||
@@ -16,4 +16,6 @@ public interface IMediaCacheService
|
||||
Task DeleteItemAsync(IContentBase media);
|
||||
|
||||
Task SeedAsync(CancellationToken cancellationToken);
|
||||
|
||||
void Rebuild(IReadOnlyCollection<int> contentTypeIds);
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ using Umbraco.Cms.Core.Scoping;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Infrastructure.HybridCache.Factories;
|
||||
using Umbraco.Cms.Infrastructure.HybridCache.Persistence;
|
||||
using Umbraco.Cms.Infrastructure.HybridCache.Serialization;
|
||||
|
||||
namespace Umbraco.Cms.Infrastructure.HybridCache.Services;
|
||||
|
||||
@@ -164,6 +165,26 @@ internal class MediaCacheService : IMediaCacheService
|
||||
scope.Complete();
|
||||
}
|
||||
|
||||
public void Rebuild(IReadOnlyCollection<int> contentTypeIds)
|
||||
{
|
||||
using ICoreScope scope = _scopeProvider.CreateCoreScope();
|
||||
_databaseCacheRepository.Rebuild(contentTypeIds.ToList());
|
||||
|
||||
IEnumerable<Guid> mediaTypeKeys = contentTypeIds.Select(x => _idKeyMap.GetKeyForId(x, UmbracoObjectTypes.MediaType))
|
||||
.Where(x => x.Success)
|
||||
.Select(x => x.Result);
|
||||
|
||||
IEnumerable<ContentCacheNode> mediaCacheNodesByContentTypeKey =
|
||||
_databaseCacheRepository.GetContentByContentTypeKey(mediaTypeKeys, ContentCacheDataSerializerEntityType.Media);
|
||||
|
||||
foreach (ContentCacheNode media in mediaCacheNodesByContentTypeKey)
|
||||
{
|
||||
_hybridCache.RemoveAsync(GetCacheKey(media.Key, false));
|
||||
}
|
||||
|
||||
scope.Complete();
|
||||
}
|
||||
|
||||
private HybridCacheEntryOptions GetSeedEntryOptions() => new()
|
||||
{
|
||||
Expiration = _cacheSettings.SeedCacheDuration, LocalCacheExpiration = _cacheSettings.SeedCacheDuration,
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
using Umbraco.Cms.Core.Models.ContentEditing;
|
||||
using Umbraco.Cms.Tests.Common.Builders.Interfaces;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Common.Builders;
|
||||
|
||||
public abstract class ContentEditingBaseBuilder<TCreateModel> : BuilderBase<TCreateModel>,
|
||||
IWithInvariantNameBuilder,
|
||||
IWithKeyBuilder,
|
||||
IWithContentTypeKeyBuilder,
|
||||
IWithParentKeyBuilder,
|
||||
IBuildContentTypes
|
||||
where TCreateModel : ContentCreationModelBase, new()
|
||||
{
|
||||
protected TCreateModel _model = new();
|
||||
private List<ContentEditingPropertyValueBuilder<ContentEditingBaseBuilder<TCreateModel>>> _invariantProperties = [];
|
||||
private List<ContentEditingVariantBuilder<ContentEditingBaseBuilder<TCreateModel>>> _variants = [];
|
||||
private Guid _contentTypeKey;
|
||||
private Guid? _parentKey;
|
||||
private Guid? _key;
|
||||
private string _invariantName;
|
||||
|
||||
Guid? IWithKeyBuilder.Key
|
||||
{
|
||||
get => _key;
|
||||
set => _key = value;
|
||||
}
|
||||
|
||||
string IWithInvariantNameBuilder.InvariantName
|
||||
{
|
||||
get => _invariantName;
|
||||
set => _invariantName = value;
|
||||
}
|
||||
|
||||
Guid? IWithParentKeyBuilder.ParentKey
|
||||
{
|
||||
get => _parentKey;
|
||||
set => _parentKey = value;
|
||||
}
|
||||
|
||||
Guid IWithContentTypeKeyBuilder.ContentTypeKey
|
||||
{
|
||||
get => _contentTypeKey;
|
||||
set => _contentTypeKey = value;
|
||||
}
|
||||
|
||||
public ContentEditingPropertyValueBuilder<ContentEditingBaseBuilder<TCreateModel>> AddInvariantProperty()
|
||||
{
|
||||
var builder = new ContentEditingPropertyValueBuilder<ContentEditingBaseBuilder<TCreateModel>>(this);
|
||||
_invariantProperties.Add(builder);
|
||||
return builder;
|
||||
}
|
||||
|
||||
public ContentEditingVariantBuilder<ContentEditingBaseBuilder<TCreateModel>> AddVariant()
|
||||
{
|
||||
var builder = new ContentEditingVariantBuilder<ContentEditingBaseBuilder<TCreateModel>>(this);
|
||||
_variants.Add(builder);
|
||||
return builder;
|
||||
}
|
||||
|
||||
public override TCreateModel Build()
|
||||
{
|
||||
if (_parentKey is not null)
|
||||
{
|
||||
_model.ParentKey = _parentKey;
|
||||
}
|
||||
|
||||
_model.InvariantName = _invariantName ?? Guid.NewGuid().ToString();
|
||||
_model.ContentTypeKey = _contentTypeKey;
|
||||
_model.Key = _key ?? Guid.NewGuid();
|
||||
_model.InvariantProperties = _invariantProperties.Select(x => x.Build()).ToList();
|
||||
_model.Variants = _variants.Select(x => x.Build()).ToList();
|
||||
|
||||
return _model;
|
||||
}
|
||||
}
|
||||
@@ -4,65 +4,12 @@
|
||||
using Umbraco.Cms.Core.Models.ContentEditing;
|
||||
using Umbraco.Cms.Tests.Common.Builders.Extensions;
|
||||
using Umbraco.Cms.Tests.Common.Builders.Interfaces;
|
||||
using Umbraco.Cms.Tests.Common.Builders.Interfaces.ContentCreateModel;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Common.Builders;
|
||||
|
||||
public class ContentEditingBuilder
|
||||
: BuilderBase<ContentCreateModel>,
|
||||
IWithInvariantNameBuilder,
|
||||
IWithInvariantPropertiesBuilder,
|
||||
IWithVariantsBuilder,
|
||||
IWithKeyBuilder,
|
||||
IWithContentTypeKeyBuilder,
|
||||
IWithParentKeyBuilder,
|
||||
IWithTemplateKeyBuilder,
|
||||
IBuildContentTypes
|
||||
public class ContentEditingBuilder : ContentEditingBaseBuilder<ContentCreateModel>, IWithTemplateKeyBuilder
|
||||
{
|
||||
private ContentTypeEditingBuilder _contentTypeEditingBuilder;
|
||||
private IEnumerable<PropertyValueModel> _invariantProperties = [];
|
||||
private IEnumerable<VariantModel> _variants = [];
|
||||
private Guid _contentTypeKey;
|
||||
private Guid? _parentKey;
|
||||
private Guid? _templateKey;
|
||||
private Guid? _key;
|
||||
private string _invariantName;
|
||||
|
||||
Guid? IWithKeyBuilder.Key
|
||||
{
|
||||
get => _key;
|
||||
set => _key = value;
|
||||
}
|
||||
|
||||
string IWithInvariantNameBuilder.InvariantName
|
||||
{
|
||||
get => _invariantName;
|
||||
set => _invariantName = value;
|
||||
}
|
||||
|
||||
IEnumerable<PropertyValueModel> IWithInvariantPropertiesBuilder.InvariantProperties
|
||||
{
|
||||
get => _invariantProperties;
|
||||
set => _invariantProperties = value;
|
||||
}
|
||||
|
||||
IEnumerable<VariantModel> IWithVariantsBuilder.Variants
|
||||
{
|
||||
get => _variants;
|
||||
set => _variants = value;
|
||||
}
|
||||
|
||||
Guid? IWithParentKeyBuilder.ParentKey
|
||||
{
|
||||
get => _parentKey;
|
||||
set => _parentKey = value;
|
||||
}
|
||||
|
||||
Guid IWithContentTypeKeyBuilder.ContentTypeKey
|
||||
{
|
||||
get => _contentTypeKey;
|
||||
set => _contentTypeKey = value;
|
||||
}
|
||||
|
||||
Guid? IWithTemplateKeyBuilder.TemplateKey
|
||||
{
|
||||
@@ -70,65 +17,10 @@ public class ContentEditingBuilder
|
||||
set => _templateKey = value;
|
||||
}
|
||||
|
||||
public ContentEditingBuilder WithInvariantName(string invariantName)
|
||||
{
|
||||
_invariantName = invariantName;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ContentEditingBuilder WithInvariantProperty(string alias, object value)
|
||||
{
|
||||
var property = new PropertyValueModel { Alias = alias, Value = value };
|
||||
_invariantProperties = _invariantProperties.Concat(new[] { property });
|
||||
return this;
|
||||
}
|
||||
|
||||
public ContentEditingBuilder AddVariant(string culture, string segment, string name, IEnumerable<PropertyValueModel> properties)
|
||||
{
|
||||
var variant = new VariantModel { Culture = culture, Segment = segment, Name = name, Properties = properties };
|
||||
_variants = _variants.Concat(new[] { variant });
|
||||
return this;
|
||||
}
|
||||
|
||||
public ContentEditingBuilder WithParentKey(Guid parentKey)
|
||||
{
|
||||
_parentKey = parentKey;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ContentEditingBuilder WithTemplateKey(Guid templateKey)
|
||||
{
|
||||
_templateKey = templateKey;
|
||||
return this;
|
||||
}
|
||||
|
||||
public override ContentCreateModel Build()
|
||||
{
|
||||
var key = _key ?? Guid.NewGuid();
|
||||
var parentKey = _parentKey;
|
||||
var templateKey = _templateKey;
|
||||
var invariantName = _invariantName ?? Guid.NewGuid().ToString();
|
||||
var invariantProperties = _invariantProperties;
|
||||
var variants = _variants;
|
||||
|
||||
var content = new ContentCreateModel();
|
||||
content.InvariantName = invariantName;
|
||||
if (parentKey is not null)
|
||||
{
|
||||
content.ParentKey = parentKey;
|
||||
}
|
||||
|
||||
if (templateKey is not null)
|
||||
{
|
||||
content.TemplateKey = templateKey;
|
||||
}
|
||||
|
||||
content.ContentTypeKey = _contentTypeKey;
|
||||
content.Key = key;
|
||||
content.InvariantProperties = invariantProperties;
|
||||
content.Variants = variants;
|
||||
|
||||
return content;
|
||||
_model.TemplateKey = _templateKey;
|
||||
return base.Build();
|
||||
}
|
||||
|
||||
public static ContentCreateModel CreateBasicContent(Guid contentTypeKey, Guid? key) =>
|
||||
@@ -142,7 +34,10 @@ public class ContentEditingBuilder
|
||||
new ContentEditingBuilder()
|
||||
.WithContentTypeKey(contentTypeKey)
|
||||
.WithInvariantName("Home")
|
||||
.WithInvariantProperty("title", "Welcome to our Home page")
|
||||
.AddInvariantProperty()
|
||||
.WithAlias("title")
|
||||
.WithValue("Welcome to our Home page")
|
||||
.Done()
|
||||
.Build();
|
||||
|
||||
public static ContentCreateModel CreateSimpleContent(Guid contentTypeKey, string name, Guid? parentKey) =>
|
||||
@@ -150,20 +45,65 @@ public class ContentEditingBuilder
|
||||
.WithContentTypeKey(contentTypeKey)
|
||||
.WithInvariantName(name)
|
||||
.WithParentKey(parentKey)
|
||||
.WithInvariantProperty("title", "Welcome to our Home page")
|
||||
.AddInvariantProperty()
|
||||
.WithAlias("title")
|
||||
.WithValue("Welcome to our Home page")
|
||||
.Done()
|
||||
.Build();
|
||||
|
||||
public static ContentCreateModel CreateSimpleContent(Guid contentTypeKey, string name) =>
|
||||
new ContentEditingBuilder()
|
||||
.WithContentTypeKey(contentTypeKey)
|
||||
.WithInvariantName(name)
|
||||
.WithInvariantProperty("title", "Welcome to our Home page")
|
||||
.AddInvariantProperty()
|
||||
.WithAlias("title")
|
||||
.WithValue("Welcome to our Home page")
|
||||
.Done()
|
||||
.Build();
|
||||
|
||||
public static ContentCreateModel CreateContentWithTwoInvariantProperties(Guid contentTypeKey, string name, string firstPropertyAlias, string firstPropertyValue, string secondPropertyAlias, string secondPropertyValue, Guid? parentKey) =>
|
||||
new ContentEditingBuilder()
|
||||
.WithContentTypeKey(contentTypeKey)
|
||||
.WithInvariantName(name)
|
||||
.WithParentKey(parentKey)
|
||||
.AddInvariantProperty()
|
||||
.WithAlias(firstPropertyAlias)
|
||||
.WithValue(firstPropertyValue)
|
||||
.Done()
|
||||
.AddInvariantProperty()
|
||||
.WithAlias(secondPropertyAlias)
|
||||
.WithValue(secondPropertyValue)
|
||||
.Done()
|
||||
.Build();
|
||||
|
||||
public static ContentCreateModel CreateContentWithOneInvariantProperty(Guid contentTypeKey, string name, string propertyAlias, object propertyValue) =>
|
||||
new ContentEditingBuilder()
|
||||
.WithContentTypeKey(contentTypeKey)
|
||||
.WithInvariantName(name)
|
||||
.AddInvariantProperty()
|
||||
.WithAlias(propertyAlias)
|
||||
.WithValue(propertyValue)
|
||||
.Done()
|
||||
.Build();
|
||||
|
||||
public static ContentCreateModel CreateContentWithTwoVariantProperties(Guid contentTypeKey, string firstCulture, string secondCulture, string propertyAlias, string propertyName) =>
|
||||
new ContentEditingBuilder()
|
||||
.WithContentTypeKey(contentTypeKey)
|
||||
.AddVariant(firstCulture, null, firstCulture, new[] { new PropertyValueModel { Alias = propertyAlias, Value = propertyName } })
|
||||
.AddVariant(secondCulture, null, secondCulture, new[] { new PropertyValueModel { Alias = propertyAlias, Value = propertyName } })
|
||||
.AddVariant()
|
||||
.WithCulture(firstCulture)
|
||||
.WithName(firstCulture)
|
||||
.AddProperty()
|
||||
.WithAlias(propertyAlias)
|
||||
.WithValue(propertyName)
|
||||
.Done()
|
||||
.Done()
|
||||
.AddVariant()
|
||||
.WithCulture(secondCulture)
|
||||
.WithName(secondCulture)
|
||||
.AddProperty()
|
||||
.WithAlias(propertyAlias)
|
||||
.WithValue(propertyName)
|
||||
.Done()
|
||||
.Done()
|
||||
.Build();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
using Umbraco.Cms.Core.Models.ContentEditing;
|
||||
using Umbraco.Cms.Tests.Common.Builders.Interfaces;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Common.Builders;
|
||||
|
||||
public class ContentEditingPropertyValueBuilder<TParent>(TParent parentBuilder)
|
||||
: ChildBuilderBase<TParent, PropertyValueModel>(parentBuilder), IWithAliasBuilder, IWithValueBuilder
|
||||
{
|
||||
private string _alias;
|
||||
private object? _value;
|
||||
|
||||
string IWithAliasBuilder.Alias
|
||||
{
|
||||
get => _alias;
|
||||
set => _alias = value;
|
||||
}
|
||||
|
||||
object? IWithValueBuilder.Value
|
||||
{
|
||||
get => _value;
|
||||
set => _value = value;
|
||||
}
|
||||
|
||||
public override PropertyValueModel Build() => new() { Alias = _alias, Value = _value };
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
using Umbraco.Cms.Core.Models.ContentEditing;
|
||||
using Umbraco.Cms.Tests.Common.Builders.Interfaces;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Common.Builders;
|
||||
|
||||
public class ContentEditingVariantBuilder<TParent>(TParent parentBuilder)
|
||||
: ChildBuilderBase<TParent, VariantModel>(parentBuilder), IWithCultureBuilder, IWithSegmentBuilder, IWithNameBuilder
|
||||
{
|
||||
private string? _culture;
|
||||
private string? _segment;
|
||||
private string _name;
|
||||
private readonly List<ContentEditingPropertyValueBuilder<ContentEditingVariantBuilder<TParent>>> _properties = new();
|
||||
|
||||
string? IWithCultureBuilder.Culture
|
||||
{
|
||||
get => _culture;
|
||||
set => _culture = value;
|
||||
}
|
||||
|
||||
string? IWithSegmentBuilder.Segment
|
||||
{
|
||||
get => _segment;
|
||||
set => _segment = value;
|
||||
}
|
||||
|
||||
string IWithNameBuilder.Name
|
||||
{
|
||||
get => _name;
|
||||
set => _name = value;
|
||||
}
|
||||
|
||||
public ContentEditingPropertyValueBuilder<ContentEditingVariantBuilder<TParent>> AddProperty()
|
||||
{
|
||||
var builder = new ContentEditingPropertyValueBuilder<ContentEditingVariantBuilder<TParent>>((ContentEditingVariantBuilder<TParent>)this);
|
||||
_properties.Add(builder);
|
||||
return builder;
|
||||
}
|
||||
|
||||
public override VariantModel Build() =>
|
||||
new()
|
||||
{
|
||||
Culture = _culture,
|
||||
Segment = _segment,
|
||||
Name = _name,
|
||||
Properties = _properties.Select(x => x.Build()).ToList(),
|
||||
};
|
||||
}
|
||||
@@ -16,7 +16,7 @@ public class ContentTypeBuilder
|
||||
IWithPropertyTypeIdsIncrementingFrom,
|
||||
IBuildPropertyTypes
|
||||
{
|
||||
private readonly List<ContentTypeSortBuilder> _allowedContentTypeBuilders = new();
|
||||
private readonly List<ContentTypeSortBuilder<ContentTypeBuilder>> _allowedContentTypeBuilders = new();
|
||||
private readonly List<PropertyTypeBuilder<ContentTypeBuilder>> _noGroupPropertyTypeBuilders = new();
|
||||
private readonly List<PropertyGroupBuilder<ContentTypeBuilder>> _propertyGroupBuilders = new();
|
||||
private readonly List<TemplateBuilder> _templateBuilders = new();
|
||||
@@ -88,9 +88,9 @@ public class ContentTypeBuilder
|
||||
return builder;
|
||||
}
|
||||
|
||||
public ContentTypeSortBuilder AddAllowedContentType()
|
||||
public ContentTypeSortBuilder<ContentTypeBuilder> AddAllowedContentType()
|
||||
{
|
||||
var builder = new ContentTypeSortBuilder(this);
|
||||
var builder = new ContentTypeSortBuilder<ContentTypeBuilder>(this);
|
||||
_allowedContentTypeBuilders.Add(builder);
|
||||
return builder;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
using Umbraco.Cms.Core.Models.ContentTypeEditing;
|
||||
using Umbraco.Cms.Tests.Common.Builders.Interfaces;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Common.Builders;
|
||||
|
||||
public abstract class ContentTypeEditingBaseBuilder<TBuilder, TCreateModel, TPropertyType, TPropertyTypeContainer> :
|
||||
IWithAliasBuilder, IWithNameBuilder, IWithDescriptionBuilder, IWithIconBuilder, IWithAllowAsRootBuilder,
|
||||
IWithIsElementBuilder, IWithVariesByCultureBuilder,
|
||||
IWithVariesBySegmentBuilder
|
||||
where TBuilder : ContentTypeEditingBaseBuilder<TBuilder, TCreateModel, TPropertyType, TPropertyTypeContainer>
|
||||
where TCreateModel : ContentTypeEditingModelBase<TPropertyType, TPropertyTypeContainer>, new()
|
||||
where TPropertyType : PropertyTypeModelBase, new()
|
||||
where TPropertyTypeContainer : PropertyTypeContainerModelBase, new()
|
||||
{
|
||||
protected TCreateModel _model = new();
|
||||
private string _alias;
|
||||
private string _name;
|
||||
private string? _description;
|
||||
private string _icon;
|
||||
private bool? _allowedAsRoot;
|
||||
private bool? _isElement;
|
||||
private bool? _variesByCulture;
|
||||
private bool? _variesBySegment;
|
||||
private readonly List<PropertyTypeEditingBuilder<TBuilder, TPropertyType>> _propertyTypeBuilders = new();
|
||||
private readonly List<PropertyTypeContainerBuilder<TBuilder, TPropertyTypeContainer>> _propertyTypeContainerBuilders = new();
|
||||
private readonly List<ContentTypeSortBuilder<TBuilder>> _allowedContentTypeBuilders = new();
|
||||
|
||||
string IWithAliasBuilder.Alias
|
||||
{
|
||||
get => _alias;
|
||||
set => _alias = value;
|
||||
}
|
||||
|
||||
string IWithNameBuilder.Name
|
||||
{
|
||||
get => _name;
|
||||
set => _name = value;
|
||||
}
|
||||
|
||||
string? IWithDescriptionBuilder.Description
|
||||
{
|
||||
get => _description;
|
||||
set => _description = value;
|
||||
}
|
||||
|
||||
string IWithIconBuilder.Icon
|
||||
{
|
||||
get => _icon;
|
||||
set => _icon = value;
|
||||
}
|
||||
|
||||
bool? IWithAllowAsRootBuilder.AllowAsRoot
|
||||
{
|
||||
get => _allowedAsRoot ?? false;
|
||||
set => _allowedAsRoot = value;
|
||||
}
|
||||
|
||||
bool? IWithIsElementBuilder.IsElement
|
||||
{
|
||||
get => _isElement ?? false;
|
||||
set => _isElement = value;
|
||||
}
|
||||
|
||||
|
||||
bool IWithVariesByCultureBuilder.VariesByCulture
|
||||
{
|
||||
get => _variesByCulture ?? false;
|
||||
set => _variesByCulture = value;
|
||||
}
|
||||
|
||||
bool IWithVariesBySegmentBuilder.VariesBySegment
|
||||
{
|
||||
get => _variesBySegment ?? false;
|
||||
set => _variesBySegment = value;
|
||||
}
|
||||
|
||||
public PropertyTypeEditingBuilder<TBuilder, TPropertyType> AddPropertyType()
|
||||
{
|
||||
var builder = new PropertyTypeEditingBuilder<TBuilder, TPropertyType>((TBuilder)this);
|
||||
_propertyTypeBuilders.Add(builder);
|
||||
return builder;
|
||||
}
|
||||
|
||||
public PropertyTypeContainerBuilder<TBuilder, TPropertyTypeContainer> AddPropertyGroup()
|
||||
{
|
||||
var builder = new PropertyTypeContainerBuilder<TBuilder, TPropertyTypeContainer>((TBuilder)this);
|
||||
_propertyTypeContainerBuilders.Add(builder);
|
||||
return builder;
|
||||
}
|
||||
|
||||
public ContentTypeSortBuilder<TBuilder> AddAllowedContentType()
|
||||
{
|
||||
var builder = new ContentTypeSortBuilder<TBuilder>((TBuilder)this);
|
||||
_allowedContentTypeBuilders.Add(builder);
|
||||
return builder;
|
||||
}
|
||||
|
||||
protected virtual TCreateModel Build()
|
||||
{
|
||||
_model.Properties = _propertyTypeBuilders.Select(x => x.Build());
|
||||
_model.Containers = _propertyTypeContainerBuilders.Select(x => x.Build());
|
||||
_model.AllowedContentTypes = _allowedContentTypeBuilders.Select(x => x.Build());
|
||||
_model.Alias = _alias ?? "TestName";
|
||||
_model.Name = _name ?? "TestName";
|
||||
_model.Description = _description;
|
||||
_model.Icon = _icon ?? _model.Icon;
|
||||
_model.AllowedAsRoot = _allowedAsRoot ?? false;
|
||||
_model.IsElement = _isElement ?? _model.IsElement;
|
||||
_model.VariesByCulture = _variesByCulture ?? _model.VariesByCulture;
|
||||
_model.VariesBySegment = _variesBySegment ?? _model.VariesBySegment;
|
||||
return _model;
|
||||
}
|
||||
}
|
||||
@@ -1,70 +1,33 @@
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.ContentTypeEditing;
|
||||
using Umbraco.Cms.Tests.Common.Builders.Extensions;
|
||||
using Umbraco.Cms.Tests.Common.Builders.Interfaces;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Common.Builders;
|
||||
|
||||
public class ContentTypeEditingBuilder
|
||||
: ContentTypeBaseBuilder<ContentEditingBuilder, ContentTypeCreateModel>,
|
||||
IBuildPropertyTypes
|
||||
public class ContentTypeEditingBuilder : ContentTypeEditingBaseBuilder<ContentTypeEditingBuilder, ContentTypeCreateModel, ContentTypePropertyTypeModel, ContentTypePropertyContainerModel>, IWithKeyBuilder, IWithContainerKeyBuilder, IWithDefaultTemplateKeyBuilder
|
||||
{
|
||||
private Guid? _key;
|
||||
private Guid? _containerKey;
|
||||
private ContentTypeCleanup _cleanup = new();
|
||||
private IEnumerable<Guid> _allowedTemplateKeys;
|
||||
private IEnumerable<Guid> _allowedTemplateKeys = Array.Empty<Guid>();
|
||||
private Guid? _defaultTemplateKey;
|
||||
private bool? _allowAtRoot;
|
||||
private bool? _isElement;
|
||||
private bool? _variesByCulture;
|
||||
private bool? _variesBySegment;
|
||||
private readonly List<PropertyTypeEditingBuilder> _propertyTypeBuilders = [];
|
||||
private readonly List<PropertyTypeContainerBuilder<ContentTypeEditingBuilder>> _propertyTypeContainerBuilders = [];
|
||||
private readonly List<ContentTypeSortBuilder> _allowedContentTypeBuilders = [];
|
||||
|
||||
public ContentTypeEditingBuilder()
|
||||
: base(null)
|
||||
Guid? IWithKeyBuilder.Key
|
||||
{
|
||||
get => _key;
|
||||
set => _key = value;
|
||||
}
|
||||
|
||||
public ContentTypeEditingBuilder(ContentEditingBuilder parentBuilder)
|
||||
: base(parentBuilder)
|
||||
Guid? IWithContainerKeyBuilder.ContainerKey
|
||||
{
|
||||
get => _containerKey;
|
||||
set => _containerKey = value;
|
||||
}
|
||||
|
||||
public ContentTypeEditingBuilder WithDefaultTemplateKey(Guid templateKey)
|
||||
Guid? IWithDefaultTemplateKeyBuilder.DefaultTemplateKey
|
||||
{
|
||||
_defaultTemplateKey = templateKey;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ContentTypeEditingBuilder WithIsElement(bool isElement)
|
||||
{
|
||||
_isElement = isElement;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PropertyTypeContainerBuilder<ContentTypeEditingBuilder> AddPropertyGroup()
|
||||
{
|
||||
var builder = new PropertyTypeContainerBuilder<ContentTypeEditingBuilder>(this);
|
||||
_propertyTypeContainerBuilders.Add(builder);
|
||||
return builder;
|
||||
}
|
||||
|
||||
public PropertyTypeEditingBuilder AddPropertyType()
|
||||
{
|
||||
var builder = new PropertyTypeEditingBuilder(this);
|
||||
_propertyTypeBuilders.Add(builder);
|
||||
return builder;
|
||||
}
|
||||
|
||||
|
||||
public ContentTypeSortBuilder AddAllowedContentType()
|
||||
{
|
||||
var builder = new ContentTypeSortBuilder(this);
|
||||
_allowedContentTypeBuilders.Add(builder);
|
||||
return builder;
|
||||
get => _defaultTemplateKey;
|
||||
set => _defaultTemplateKey = value;
|
||||
}
|
||||
|
||||
public ContentTypeEditingBuilder AddAllowedTemplateKeys(IEnumerable<Guid> templateKeys)
|
||||
@@ -73,64 +36,33 @@ public class ContentTypeEditingBuilder
|
||||
return this;
|
||||
}
|
||||
|
||||
public ContentTypeEditingBuilder WithAllowAtRoot(bool allowAtRoot)
|
||||
protected override ContentTypeCreateModel Build()
|
||||
{
|
||||
_allowAtRoot = allowAtRoot;
|
||||
return this;
|
||||
_model.Key = _key ?? Guid.NewGuid();
|
||||
_model.ContainerKey = _containerKey;
|
||||
_model.AllowedTemplateKeys = _allowedTemplateKeys;
|
||||
_model.DefaultTemplateKey = _defaultTemplateKey;
|
||||
base.Build();
|
||||
return _model;
|
||||
}
|
||||
|
||||
public ContentTypeEditingBuilder WithVariesByCulture(bool variesByCulture)
|
||||
{
|
||||
_variesByCulture = variesByCulture;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ContentTypeEditingBuilder WithVariesBySegment(bool variesBySegment)
|
||||
{
|
||||
_variesBySegment = variesBySegment;
|
||||
return this;
|
||||
}
|
||||
|
||||
public override ContentTypeCreateModel Build()
|
||||
{
|
||||
ContentTypeCreateModel contentType = new ContentTypeCreateModel();
|
||||
contentType.Name = GetName();
|
||||
contentType.Alias = GetAlias();
|
||||
contentType.Key = GetKey();
|
||||
contentType.ContainerKey = _containerKey;
|
||||
contentType.Cleanup = _cleanup;
|
||||
contentType.AllowedTemplateKeys = _allowedTemplateKeys ?? Array.Empty<Guid>();
|
||||
contentType.DefaultTemplateKey = _defaultTemplateKey;
|
||||
contentType.IsElement = _isElement ?? false;
|
||||
contentType.VariesByCulture = _variesByCulture ?? false;
|
||||
contentType.VariesBySegment = _variesBySegment ?? false;
|
||||
contentType.AllowedAsRoot = _allowAtRoot ?? false;
|
||||
contentType.Properties = _propertyTypeBuilders.Select(x => x.Build());
|
||||
contentType.Containers = _propertyTypeContainerBuilders.Select(x => x.Build());
|
||||
contentType.AllowedContentTypes = _allowedContentTypeBuilders.Select(x => x.Build());
|
||||
|
||||
return contentType;
|
||||
}
|
||||
|
||||
public static ContentTypeCreateModel CreateBasicContentType(string alias = "umbTextpage", string name = "TextPage", IContentType parent = null)
|
||||
public static ContentTypeCreateModel CreateBasicContentType(string alias = "umbTextpage", string name = "TextPage")
|
||||
{
|
||||
var builder = new ContentTypeEditingBuilder();
|
||||
return (ContentTypeCreateModel)builder
|
||||
.WithAlias(alias)
|
||||
.WithName(name)
|
||||
.WithParentContentType(parent)
|
||||
.Build();
|
||||
}
|
||||
|
||||
public static ContentTypeCreateModel CreateSimpleContentType(string alias = "umbTextpage", string name = "TextPage", IContentType parent = null, string propertyGroupName = "Content", Guid? defaultTemplateKey = null)
|
||||
public static ContentTypeCreateModel CreateSimpleContentType(string alias = "umbTextpage", string name = "TextPage", string propertyGroupName = "Content", Guid? defaultTemplateKey = null)
|
||||
{
|
||||
var containerKey = Guid.NewGuid();
|
||||
var builder = new ContentTypeEditingBuilder();
|
||||
return (ContentTypeCreateModel)builder
|
||||
.WithAlias(alias)
|
||||
.WithName(name)
|
||||
.WithAllowAtRoot(true)
|
||||
.WithParentContentType(parent)
|
||||
.WithAllowAsRoot(true)
|
||||
.AddPropertyGroup()
|
||||
.WithKey(containerKey)
|
||||
.WithName(propertyGroupName)
|
||||
@@ -155,7 +87,7 @@ public class ContentTypeEditingBuilder
|
||||
return (ContentTypeCreateModel)builder
|
||||
.WithAlias(alias)
|
||||
.WithName(name)
|
||||
.WithAllowAtRoot(true)
|
||||
.WithAllowAsRoot(true)
|
||||
.AddPropertyGroup()
|
||||
.WithName("Content")
|
||||
.WithKey(containerKeyOne)
|
||||
@@ -237,4 +169,53 @@ public class ContentTypeEditingBuilder
|
||||
.Done()
|
||||
.Build();
|
||||
}
|
||||
|
||||
public static ContentTypeCreateModel CreateContentTypeWithContentPicker(string alias = "test", string name = "TestName", Guid templateKey = default)
|
||||
{
|
||||
var containerKey = Guid.NewGuid();
|
||||
var builder = new ContentTypeEditingBuilder();
|
||||
return (ContentTypeCreateModel)builder
|
||||
.WithAlias(alias)
|
||||
.WithName(name)
|
||||
.WithAllowAsRoot(true)
|
||||
.AddAllowedTemplateKeys([templateKey])
|
||||
.AddPropertyGroup()
|
||||
.WithName("Content")
|
||||
.WithKey(containerKey)
|
||||
.Done()
|
||||
.AddPropertyType()
|
||||
.WithAlias("contentPicker")
|
||||
.WithName("Content Picker")
|
||||
.WithDataTypeKey(Constants.DataTypes.Guids.ContentPickerGuid)
|
||||
.WithContainerKey(containerKey)
|
||||
.Done()
|
||||
.Build();
|
||||
}
|
||||
|
||||
public static ContentTypeCreateModel CreateContentTypeWithTwoPropertiesOneVariantAndOneInvariant(string alias = "test", string name = "TestName", string variantPropertyAlias = "variant", string variantPropertyName = "Variant", string invariantAlias = "invariant", string invariantName = "Invariant")
|
||||
{
|
||||
var containerKey = Guid.NewGuid();
|
||||
var builder = new ContentTypeEditingBuilder();
|
||||
return (ContentTypeCreateModel)builder
|
||||
.WithAlias(alias)
|
||||
.WithName(name)
|
||||
.WithAllowAsRoot(true)
|
||||
.WithVariesByCulture(true)
|
||||
.AddPropertyGroup()
|
||||
.WithName("Content")
|
||||
.WithKey(containerKey)
|
||||
.Done()
|
||||
.AddPropertyType()
|
||||
.WithAlias(variantPropertyAlias)
|
||||
.WithName(variantPropertyName)
|
||||
.WithVariesByCulture(true)
|
||||
.WithContainerKey(containerKey)
|
||||
.Done()
|
||||
.AddPropertyType()
|
||||
.WithAlias(invariantAlias)
|
||||
.WithName(invariantName)
|
||||
.WithContainerKey(containerKey)
|
||||
.Done()
|
||||
.Build();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,8 +8,8 @@ using Umbraco.Cms.Tests.Common.Builders.Interfaces;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Common.Builders;
|
||||
|
||||
public class ContentTypeSortBuilder
|
||||
: ChildBuilderBase<ContentTypeBuilder, ContentTypeSort>,
|
||||
public class ContentTypeSortBuilder<TBuilder>
|
||||
: ChildBuilderBase<TBuilder, ContentTypeSort>,
|
||||
IWithKeyBuilder,
|
||||
IWithAliasBuilder,
|
||||
IWithSortOrderBuilder
|
||||
@@ -18,21 +18,11 @@ public class ContentTypeSortBuilder
|
||||
private string _alias;
|
||||
private int? _sortOrder;
|
||||
|
||||
public ContentTypeSortBuilder()
|
||||
: base(null)
|
||||
{
|
||||
}
|
||||
|
||||
public ContentTypeSortBuilder(ContentTypeBuilder parentBuilder)
|
||||
public ContentTypeSortBuilder(TBuilder parentBuilder)
|
||||
: base(parentBuilder)
|
||||
{
|
||||
}
|
||||
|
||||
public ContentTypeSortBuilder(ContentTypeEditingBuilder parentBuilder)
|
||||
: base(null)
|
||||
{
|
||||
}
|
||||
|
||||
string IWithAliasBuilder.Alias
|
||||
{
|
||||
get => _alias;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
// Copyright (c) Umbraco.
|
||||
// See LICENSE for more details.
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Tests.Common.Builders.Interfaces;
|
||||
@@ -233,7 +232,8 @@ public static class BuilderExtensions
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static T WithPropertyValues<T>(this T builder, object propertyValues, string? culture = null, string? segment = null)
|
||||
public static T WithPropertyValues<T>(this T builder, object propertyValues, string? culture = null,
|
||||
string? segment = null)
|
||||
where T : IWithPropertyValues
|
||||
{
|
||||
builder.PropertyValues = propertyValues;
|
||||
@@ -247,4 +247,102 @@ public static class BuilderExtensions
|
||||
builder.Date = date;
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static T WithInvariantName<T>(this T builder, string invariantName)
|
||||
where T : IWithInvariantNameBuilder
|
||||
{
|
||||
builder.InvariantName = invariantName;
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static T WithKey<T>(this T builder, Guid? key)
|
||||
where T : IWithKeyBuilder
|
||||
{
|
||||
builder.Key = key;
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static T WithContentTypeKey<T>(this T builder, Guid contentTypeKey)
|
||||
where T : IWithContentTypeKeyBuilder
|
||||
{
|
||||
builder.ContentTypeKey = contentTypeKey;
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static T WithParentKey<T>(this T builder, Guid? parentKey)
|
||||
where T : IWithParentKeyBuilder
|
||||
{
|
||||
builder.ParentKey = parentKey;
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static T WithTemplateKey<T>(this T builder, Guid? templateKey)
|
||||
where T : IWithTemplateKeyBuilder
|
||||
{
|
||||
builder.TemplateKey = templateKey;
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static T WithValue<T>(this T builder, object? value)
|
||||
where T : IWithValueBuilder
|
||||
{
|
||||
builder.Value = value;
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static T WithCulture<T>(this T builder, string culture)
|
||||
where T : IWithCultureBuilder
|
||||
{
|
||||
builder.Culture = culture;
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static T WithAllowAsRoot<T>(this T builder, bool allowAsRoot)
|
||||
where T : IWithAllowAsRootBuilder
|
||||
{
|
||||
builder.AllowAsRoot = allowAsRoot;
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static T WithSegment<T>(this T builder, string segment)
|
||||
where T : IWithSegmentBuilder
|
||||
{
|
||||
builder.Segment = segment;
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static T WithIsElement<T>(this T builder, bool isElement)
|
||||
where T : IWithIsElementBuilder
|
||||
{
|
||||
builder.IsElement = isElement;
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static T WithVariesByCulture<T>(this T builder, bool variesByCulture)
|
||||
where T : IWithVariesByCultureBuilder
|
||||
{
|
||||
builder.VariesByCulture = variesByCulture;
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static T WithVariesBySegement<T>(this T builder, bool variesBySegment)
|
||||
where T : IWithVariesBySegmentBuilder
|
||||
{
|
||||
builder.VariesBySegment = variesBySegment;
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static T WithDefaultTemplateKey<T>(this T builder, Guid? defaultTemplateKey)
|
||||
where T : IWithDefaultTemplateKeyBuilder
|
||||
{
|
||||
builder.DefaultTemplateKey = defaultTemplateKey;
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static T WithContainerKey<T>(this T builder, Guid? containerKey)
|
||||
where T : IWithContainerKeyBuilder
|
||||
{
|
||||
builder.ContainerKey = containerKey;
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
using Umbraco.Cms.Core.Models.ContentEditing;
|
||||
using Umbraco.Cms.Tests.Common.Builders.Interfaces;
|
||||
using Umbraco.Cms.Tests.Common.Builders.Interfaces.ContentCreateModel;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Common.Builders.Extensions;
|
||||
|
||||
public static class ContentEditingBuilderExtensions
|
||||
{
|
||||
public static T WithInvariantName<T>(this T Builder, string invariantName)
|
||||
where T : IWithInvariantNameBuilder
|
||||
{
|
||||
Builder.InvariantName = invariantName;
|
||||
return Builder;
|
||||
}
|
||||
|
||||
public static T WithInvariantProperties<T>(this T Builder, IEnumerable<PropertyValueModel> invariantProperties)
|
||||
where T : IWithInvariantPropertiesBuilder
|
||||
{
|
||||
Builder.InvariantProperties = invariantProperties;
|
||||
return Builder;
|
||||
}
|
||||
|
||||
public static T WithVariants<T>(this T Builder, IEnumerable<VariantModel> variants)
|
||||
where T : IWithVariantsBuilder
|
||||
{
|
||||
Builder.Variants = variants;
|
||||
return Builder;
|
||||
}
|
||||
|
||||
public static T WithKey<T>(this T Builder, Guid? key)
|
||||
where T : IWithKeyBuilder
|
||||
{
|
||||
Builder.Key = key;
|
||||
return Builder;
|
||||
}
|
||||
|
||||
public static T WithContentTypeKey<T>(this T Builder, Guid contentTypeKey)
|
||||
where T : IWithContentTypeKeyBuilder
|
||||
{
|
||||
Builder.ContentTypeKey = contentTypeKey;
|
||||
return Builder;
|
||||
}
|
||||
|
||||
public static T WithParentKey<T>(this T Builder, Guid? parentKey)
|
||||
where T : IWithParentKeyBuilder
|
||||
{
|
||||
Builder.ParentKey = parentKey;
|
||||
return Builder;
|
||||
}
|
||||
|
||||
|
||||
public static T WithTemplateKey<T>(this T Builder, Guid? templateKey)
|
||||
where T : IWithTemplateKeyBuilder
|
||||
{
|
||||
Builder.TemplateKey = templateKey;
|
||||
return Builder;
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
using Umbraco.Cms.Core.Models.ContentEditing;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Common.Builders.Interfaces.ContentCreateModel;
|
||||
|
||||
public interface IWithInvariantPropertiesBuilder
|
||||
{
|
||||
public IEnumerable<PropertyValueModel> InvariantProperties { get; set; }
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
using Umbraco.Cms.Core.Models.ContentEditing;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Common.Builders.Interfaces.ContentCreateModel;
|
||||
|
||||
public interface IWithVariantsBuilder
|
||||
{
|
||||
public IEnumerable<VariantModel> Variants { get; set; }
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
namespace Umbraco.Cms.Tests.Common.Builders.Interfaces;
|
||||
|
||||
public interface IWIthContainerKeyBuilder
|
||||
public interface IWithContainerKeyBuilder
|
||||
{
|
||||
Guid? ContainerKey { get; set; }
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Umbraco.Cms.Tests.Common.Builders.Interfaces.ContentCreateModel;
|
||||
namespace Umbraco.Cms.Tests.Common.Builders.Interfaces;
|
||||
|
||||
public interface IWithContentTypeKeyBuilder
|
||||
{
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace Umbraco.Cms.Tests.Common.Builders.Interfaces;
|
||||
|
||||
public interface IWithCultureBuilder
|
||||
{
|
||||
string? Culture { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace Umbraco.Cms.Tests.Common.Builders.Interfaces;
|
||||
|
||||
public interface IWithDefaultTemplateKeyBuilder
|
||||
{
|
||||
Guid? DefaultTemplateKey { get; set; }
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Umbraco.Cms.Tests.Common.Builders.Interfaces.ContentCreateModel;
|
||||
namespace Umbraco.Cms.Tests.Common.Builders.Interfaces;
|
||||
|
||||
public interface IWithInvariantNameBuilder
|
||||
{
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace Umbraco.Cms.Tests.Common.Builders.Interfaces;
|
||||
|
||||
public interface IWithIsElementBuilder
|
||||
{
|
||||
bool? IsElement { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace Umbraco.Cms.Tests.Common.Builders.Interfaces;
|
||||
|
||||
public interface IWithSegmentBuilder
|
||||
{
|
||||
string Segment { get; set; }
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Umbraco.Cms.Tests.Common.Builders.Interfaces.ContentCreateModel;
|
||||
namespace Umbraco.Cms.Tests.Common.Builders.Interfaces;
|
||||
|
||||
public interface IWithTemplateKeyBuilder
|
||||
{
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace Umbraco.Cms.Tests.Common.Builders.Interfaces;
|
||||
|
||||
public interface IWithValueBuilder
|
||||
{
|
||||
object? Value { get; set; }
|
||||
}
|
||||
32
tests/Umbraco.Tests.Common/Builders/MediaEditingBuilder.cs
Normal file
32
tests/Umbraco.Tests.Common/Builders/MediaEditingBuilder.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using Umbraco.Cms.Core.Models.ContentEditing;
|
||||
using Umbraco.Cms.Tests.Common.Builders.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Common.Builders;
|
||||
|
||||
public class MediaEditingBuilder : ContentEditingBaseBuilder<MediaCreateModel>
|
||||
{
|
||||
public static MediaCreateModel CreateBasicMedia(Guid mediaTypeKey, Guid? key) =>
|
||||
new MediaEditingBuilder()
|
||||
.WithKey(key)
|
||||
.WithContentTypeKey(mediaTypeKey)
|
||||
.WithInvariantName("Media")
|
||||
.Build();
|
||||
|
||||
public static MediaCreateModel CreateSimpleMedia(Guid mediaTypeKey, string name, Guid? parentKey) =>
|
||||
new MediaEditingBuilder()
|
||||
.WithContentTypeKey(mediaTypeKey)
|
||||
.WithInvariantName(name)
|
||||
.WithParentKey(parentKey)
|
||||
.Build();
|
||||
|
||||
public static MediaCreateModel CreateMediaWithAProperty(Guid mediaTypeKey, string name, Guid? parentKey, string propertyAlias = "testProperty", string propertyValue = "TestValue") =>
|
||||
new MediaEditingBuilder()
|
||||
.WithContentTypeKey(mediaTypeKey)
|
||||
.WithInvariantName(name)
|
||||
.WithParentKey(parentKey)
|
||||
.AddInvariantProperty()
|
||||
.WithAlias(propertyAlias)
|
||||
.WithValue(propertyValue)
|
||||
.Done()
|
||||
.Build();
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models.ContentTypeEditing;
|
||||
using Umbraco.Cms.Tests.Common.Builders.Extensions;
|
||||
using Umbraco.Cms.Tests.Common.Builders.Interfaces;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Common.Builders;
|
||||
|
||||
public class MediaTypeEditingBuilder : ContentTypeEditingBaseBuilder<MediaTypeEditingBuilder, MediaTypeCreateModel,
|
||||
MediaTypePropertyTypeModel, MediaTypePropertyContainerModel>, IWithKeyBuilder, IWithContainerKeyBuilder
|
||||
{
|
||||
private Guid? _key;
|
||||
private Guid? _containerKey;
|
||||
|
||||
Guid? IWithKeyBuilder.Key
|
||||
{
|
||||
get => _key;
|
||||
set => _key = value;
|
||||
}
|
||||
|
||||
Guid? IWithContainerKeyBuilder.ContainerKey
|
||||
{
|
||||
get => _containerKey;
|
||||
set => _containerKey = value;
|
||||
}
|
||||
|
||||
protected override MediaTypeCreateModel Build()
|
||||
{
|
||||
_model.Key = _key ?? Guid.NewGuid();
|
||||
_model.ContainerKey = _containerKey;
|
||||
base.Build();
|
||||
return _model;
|
||||
}
|
||||
|
||||
public static MediaTypeCreateModel CreateBasicMediaType(string alias = "umbImage", string name = "Image")
|
||||
{
|
||||
var builder = new MediaTypeEditingBuilder();
|
||||
return (MediaTypeCreateModel)builder
|
||||
.WithAlias(alias)
|
||||
.WithName(name)
|
||||
.WithAllowAsRoot(true)
|
||||
.Build();
|
||||
}
|
||||
|
||||
public static MediaTypeCreateModel CreateBasicFolderMediaType(string alias = "basicFolder",
|
||||
string name = "BasicFolder")
|
||||
{
|
||||
var builder = new MediaTypeEditingBuilder();
|
||||
return (MediaTypeCreateModel)builder
|
||||
.WithAlias(alias)
|
||||
.WithName(name)
|
||||
.WithIcon("icon-folder")
|
||||
.WithAllowAsRoot(true)
|
||||
.Build();
|
||||
}
|
||||
|
||||
public static MediaTypeCreateModel CreateMediaTypeWithOneProperty(string alias = "testMediaType", string name = "TestMediaType", string propertyAlias = "testProperty", string propertyName = "TestProperty")
|
||||
{
|
||||
var containerKey = Guid.NewGuid();
|
||||
var builder = new MediaTypeEditingBuilder();
|
||||
return (MediaTypeCreateModel)builder
|
||||
.WithAlias(alias)
|
||||
.WithName(name)
|
||||
.WithAllowAsRoot(true)
|
||||
.AddPropertyGroup()
|
||||
.WithName("TestGroup")
|
||||
.WithKey(containerKey)
|
||||
.Done()
|
||||
.AddPropertyType()
|
||||
.WithAlias(propertyAlias)
|
||||
.WithName(propertyName)
|
||||
.WithDataTypeKey(Constants.DataTypes.Guids.TextstringGuid)
|
||||
.WithContainerKey(containerKey)
|
||||
.Done()
|
||||
.Build();
|
||||
}
|
||||
}
|
||||
@@ -3,12 +3,14 @@ using Umbraco.Cms.Tests.Common.Builders.Interfaces;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Common.Builders;
|
||||
|
||||
public class PropertyTypeAppearanceBuilder
|
||||
: ChildBuilderBase<PropertyTypeEditingBuilder, PropertyTypeAppearance>, IBuildPropertyTypes, IWithLabelOnTop
|
||||
public class PropertyTypeAppearanceBuilder<TParent, TModel>
|
||||
: ChildBuilderBase<PropertyTypeEditingBuilder<TParent, TModel>, PropertyTypeAppearance>, IBuildPropertyTypes, IWithLabelOnTop
|
||||
where TModel : PropertyTypeModelBase, new()
|
||||
{
|
||||
private bool? _labelOnTop;
|
||||
|
||||
public PropertyTypeAppearanceBuilder(PropertyTypeEditingBuilder parentBuilder) : base(parentBuilder)
|
||||
public PropertyTypeAppearanceBuilder(PropertyTypeEditingBuilder<TParent, TModel> parentBuilder)
|
||||
: base(parentBuilder)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.ContentTypeEditing;
|
||||
using Umbraco.Cms.Core.Models.ContentTypeEditing;
|
||||
using Umbraco.Cms.Tests.Common.Builders.Interfaces;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Common.Builders;
|
||||
|
||||
public class PropertyTypeContainerBuilder<TParent>(TParent parentBuilder)
|
||||
: ChildBuilderBase<TParent, ContentTypePropertyContainerModel>(parentBuilder),
|
||||
IBuildPropertyTypes, IWithKeyBuilder, IWithParentKeyBuilder, IWithNameBuilder, IWithTypeBuilder,
|
||||
IWithSortOrderBuilder
|
||||
public class PropertyTypeContainerBuilder<TParent, TModel>(TParent parentBuilder)
|
||||
: ChildBuilderBase<TParent, TModel>(parentBuilder), IWithKeyBuilder, IWithParentKeyBuilder, IWithNameBuilder, IWithTypeBuilder, IWithSortOrderBuilder where TModel : PropertyTypeContainerModelBase, new()
|
||||
{
|
||||
private readonly TModel _model = new();
|
||||
private Guid? _key;
|
||||
private Guid? _parentKey;
|
||||
private string _name;
|
||||
@@ -45,22 +43,18 @@ public class PropertyTypeContainerBuilder<TParent>(TParent parentBuilder)
|
||||
set => _sortOrder = value;
|
||||
}
|
||||
|
||||
public override ContentTypePropertyContainerModel Build()
|
||||
public override TModel Build()
|
||||
{
|
||||
var key = _key ?? Guid.NewGuid();
|
||||
var parentKey = _parentKey;
|
||||
var name = _name ?? "Container";
|
||||
var type = _type ?? "Group";
|
||||
var sortOrder = _sortOrder ?? 0;
|
||||
_model.Key = _key ?? Guid.NewGuid();
|
||||
|
||||
|
||||
return new ContentTypePropertyContainerModel
|
||||
if (_parentKey is not null)
|
||||
{
|
||||
Key = key,
|
||||
ParentKey = parentKey,
|
||||
Name = name,
|
||||
Type = type,
|
||||
SortOrder = sortOrder,
|
||||
};
|
||||
_model.ParentKey = _parentKey;
|
||||
}
|
||||
|
||||
_model.Name = _name ?? "Container";
|
||||
_model.Type = _type ?? "Group";
|
||||
_model.SortOrder = _sortOrder ?? 0;
|
||||
return _model;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,28 +4,30 @@ using Umbraco.Cms.Tests.Common.Builders.Interfaces;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Common.Builders;
|
||||
|
||||
public class PropertyTypeEditingBuilder
|
||||
: ChildBuilderBase<ContentTypeEditingBuilder, ContentTypePropertyTypeModel>, IBuildPropertyTypes, IWithKeyBuilder,
|
||||
IWIthContainerKeyBuilder,
|
||||
IWithSortOrderBuilder, IWithAliasBuilder, IWithNameBuilder, IWithDescriptionBuilder, IWithDataTypeKeyBuilder,
|
||||
IWithVariesByCultureBuilder, IWithVariesBySegmentBuilder
|
||||
public class PropertyTypeEditingBuilder<TParent, TModel> : ChildBuilderBase<TParent, TModel>, IWithKeyBuilder,
|
||||
IWithContainerKeyBuilder, IWithSortOrderBuilder, IWithAliasBuilder, IWithNameBuilder, IWithDescriptionBuilder,
|
||||
IWithDataTypeKeyBuilder, IWithVariesByCultureBuilder,
|
||||
IWithVariesBySegmentBuilder where TModel : PropertyTypeModelBase, new()
|
||||
{
|
||||
private TModel _model;
|
||||
private Guid? _key;
|
||||
private Guid? _containerKey;
|
||||
private int? _sortOrder;
|
||||
private string _alias;
|
||||
private string? _name;
|
||||
private string _name;
|
||||
private string? _description;
|
||||
private Guid? _dataTypeKey;
|
||||
private bool _variesByCulture;
|
||||
private bool _variesBySegment;
|
||||
private PropertyTypeValidationEditingBuilder _validationBuilder;
|
||||
private PropertyTypeAppearanceBuilder _appearanceBuilder;
|
||||
private PropertyTypeValidationEditingBuilder<TParent, TModel> _validationBuilder;
|
||||
private PropertyTypeAppearanceBuilder<TParent, TModel> _appearanceBuilder;
|
||||
|
||||
public PropertyTypeEditingBuilder(ContentTypeEditingBuilder parentBuilder) : base(parentBuilder)
|
||||
public PropertyTypeEditingBuilder(TParent parentBuilder)
|
||||
: base(parentBuilder)
|
||||
{
|
||||
_validationBuilder = new PropertyTypeValidationEditingBuilder(this);
|
||||
_appearanceBuilder = new PropertyTypeAppearanceBuilder(this);
|
||||
_model = new TModel();
|
||||
_validationBuilder = new PropertyTypeValidationEditingBuilder<TParent, TModel>(this);
|
||||
_appearanceBuilder = new PropertyTypeAppearanceBuilder<TParent, TModel>(this);
|
||||
}
|
||||
|
||||
Guid? IWithKeyBuilder.Key
|
||||
@@ -34,7 +36,7 @@ public class PropertyTypeEditingBuilder
|
||||
set => _key = value;
|
||||
}
|
||||
|
||||
Guid? IWIthContainerKeyBuilder.ContainerKey
|
||||
Guid? IWithContainerKeyBuilder.ContainerKey
|
||||
{
|
||||
get => _containerKey;
|
||||
set => _containerKey = value;
|
||||
@@ -58,7 +60,7 @@ public class PropertyTypeEditingBuilder
|
||||
set => _name = value;
|
||||
}
|
||||
|
||||
string IWithDescriptionBuilder.Description
|
||||
string? IWithDescriptionBuilder.Description
|
||||
{
|
||||
get => _description;
|
||||
set => _description = value;
|
||||
@@ -82,95 +84,34 @@ public class PropertyTypeEditingBuilder
|
||||
set => _variesBySegment = value;
|
||||
}
|
||||
|
||||
public PropertyTypeValidationEditingBuilder AddValidation()
|
||||
public PropertyTypeValidationEditingBuilder<TParent, TModel> AddValidation()
|
||||
{
|
||||
var builder = new PropertyTypeValidationEditingBuilder(this);
|
||||
var builder = new PropertyTypeValidationEditingBuilder<TParent, TModel>(this);
|
||||
_validationBuilder = builder;
|
||||
return builder;
|
||||
}
|
||||
|
||||
public PropertyTypeAppearanceBuilder AddAppearance()
|
||||
public PropertyTypeAppearanceBuilder<TParent, TModel> AddAppearance()
|
||||
{
|
||||
var builder = new PropertyTypeAppearanceBuilder(this);
|
||||
var builder = new PropertyTypeAppearanceBuilder<TParent, TModel>(this);
|
||||
_appearanceBuilder = builder;
|
||||
return builder;
|
||||
}
|
||||
|
||||
public PropertyTypeEditingBuilder WithContainerKey(Guid? containerKey)
|
||||
public override TModel Build()
|
||||
{
|
||||
_containerKey = containerKey;
|
||||
return this;
|
||||
}
|
||||
_model.Key = _key ?? Guid.NewGuid();
|
||||
_model.ContainerKey = _containerKey;
|
||||
_model.SortOrder = _sortOrder ?? 0;
|
||||
_model.Alias = _alias ?? "title";
|
||||
_model.Name = _name ?? "Title";
|
||||
_model.Description = _description;
|
||||
_model.DataTypeKey = _dataTypeKey ?? Constants.DataTypes.Guids.TextareaGuid;
|
||||
_model.VariesByCulture = _variesByCulture;
|
||||
_model.VariesBySegment = _variesBySegment;
|
||||
_model.Validation = _validationBuilder.Build();
|
||||
_model.Appearance = _appearanceBuilder.Build();
|
||||
|
||||
public PropertyTypeEditingBuilder WithSortOrder(int sortOrder)
|
||||
{
|
||||
_sortOrder = sortOrder;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PropertyTypeEditingBuilder WithAlias(string alias)
|
||||
{
|
||||
_alias = alias;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PropertyTypeEditingBuilder WithName(string name)
|
||||
{
|
||||
_name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PropertyTypeEditingBuilder WithDescription(string description)
|
||||
{
|
||||
_description = description;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PropertyTypeEditingBuilder WithDataTypeKey(Guid dataTypeKey)
|
||||
{
|
||||
_dataTypeKey = dataTypeKey;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PropertyTypeEditingBuilder WithVariesByCulture(bool variesByCulture)
|
||||
{
|
||||
_variesByCulture = variesByCulture;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PropertyTypeEditingBuilder WithVariesBySegment(bool variesBySegment)
|
||||
{
|
||||
_variesBySegment = variesBySegment;
|
||||
return this;
|
||||
}
|
||||
|
||||
public override ContentTypePropertyTypeModel Build()
|
||||
{
|
||||
var key = _key ?? Guid.NewGuid();
|
||||
var containerKey = _containerKey;
|
||||
var sortOrder = _sortOrder ?? 0;
|
||||
var alias = _alias ?? "title";
|
||||
var name = _name ?? "Title";
|
||||
var description = _description;
|
||||
var dataTypeKey = _dataTypeKey ?? Constants.DataTypes.Guids.TextareaGuid;
|
||||
var variesByCulture = _variesByCulture;
|
||||
var variesBySegment = _variesBySegment;
|
||||
var validation = _validationBuilder.Build();
|
||||
var appearance = _appearanceBuilder.Build();
|
||||
|
||||
return new ContentTypePropertyTypeModel
|
||||
{
|
||||
Key = key,
|
||||
ContainerKey = containerKey,
|
||||
SortOrder = sortOrder,
|
||||
Alias = alias,
|
||||
Name = name,
|
||||
Description = description,
|
||||
DataTypeKey = dataTypeKey,
|
||||
VariesByCulture = variesByCulture,
|
||||
VariesBySegment = variesBySegment,
|
||||
Validation = validation,
|
||||
Appearance = appearance,
|
||||
};
|
||||
return _model;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,16 +3,22 @@ using Umbraco.Cms.Tests.Common.Builders.Interfaces;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Common.Builders;
|
||||
|
||||
public class PropertyTypeValidationEditingBuilder
|
||||
: ChildBuilderBase<PropertyTypeEditingBuilder, PropertyTypeValidation>, IBuildPropertyTypes, IWithMandatoryBuilder,
|
||||
IWithMandatoryMessageBuilder, IWithRegularExpressionBuilder, IWithRegularExpressionMessage
|
||||
public class PropertyTypeValidationEditingBuilder<TParent, TModel>
|
||||
: ChildBuilderBase<PropertyTypeEditingBuilder<TParent, TModel>, PropertyTypeValidation>,
|
||||
IBuildPropertyTypes,
|
||||
IWithMandatoryBuilder,
|
||||
IWithMandatoryMessageBuilder,
|
||||
IWithRegularExpressionBuilder,
|
||||
IWithRegularExpressionMessage
|
||||
where TModel : PropertyTypeModelBase, new()
|
||||
{
|
||||
private bool? _mandatory;
|
||||
private string? _mandatoryMessage;
|
||||
private string? _regularExpression;
|
||||
private string? _regularExpressionMessage;
|
||||
|
||||
public PropertyTypeValidationEditingBuilder(PropertyTypeEditingBuilder parentBuilder) : base(parentBuilder)
|
||||
public PropertyTypeValidationEditingBuilder(PropertyTypeEditingBuilder<TParent, TModel> parentBuilder)
|
||||
: base(parentBuilder)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.ContentTypeEditing;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Common.TestHelpers;
|
||||
|
||||
public class MediaTypeUpdateHelper
|
||||
{
|
||||
public MediaTypeUpdateModel CreateMediaTypeUpdateModel(IMediaType mediaType)
|
||||
{
|
||||
var updateModel = new MediaTypeUpdateModel();
|
||||
var model = MapBaseProperties<MediaTypeUpdateModel>(mediaType, updateModel);
|
||||
return model;
|
||||
}
|
||||
|
||||
private T MapBaseProperties<T>(IMediaType mediaType, T model) where T : MediaTypeModelBase
|
||||
{
|
||||
model.Alias = mediaType.Alias;
|
||||
model.Name = mediaType.Name;
|
||||
model.Description = mediaType.Description;
|
||||
model.Icon = mediaType.Icon;
|
||||
model.AllowedAsRoot = mediaType.AllowedAsRoot;
|
||||
model.VariesByCulture = mediaType.VariesByCulture();
|
||||
model.VariesBySegment = mediaType.VariesBySegment();
|
||||
model.IsElement = mediaType.IsElement;
|
||||
model.ListView = mediaType.ListView;
|
||||
model.AllowedContentTypes = mediaType.AllowedContentTypes;
|
||||
|
||||
var tempContainerList = model.Containers.ToList();
|
||||
|
||||
foreach (var container in mediaType.PropertyGroups)
|
||||
{
|
||||
var containerModel = new MediaTypePropertyContainerModel()
|
||||
{
|
||||
Key = container.Key,
|
||||
Name = container.Name,
|
||||
SortOrder = container.SortOrder,
|
||||
Type = container.Type.ToString()
|
||||
};
|
||||
tempContainerList.Add(containerModel);
|
||||
}
|
||||
|
||||
model.Containers = tempContainerList.AsEnumerable();
|
||||
|
||||
var tempPropertyList = model.Properties.ToList();
|
||||
|
||||
foreach (var propertyType in mediaType.PropertyTypes)
|
||||
{
|
||||
var propertyModel = new MediaTypePropertyTypeModel
|
||||
{
|
||||
Key = propertyType.Key,
|
||||
ContainerKey = mediaType.PropertyGroups.Single(x => x.PropertyTypes.Contains(propertyType)).Key,
|
||||
SortOrder = propertyType.SortOrder,
|
||||
Alias = propertyType.Alias,
|
||||
Name = propertyType.Name,
|
||||
Description = propertyType.Description,
|
||||
DataTypeKey = propertyType.DataTypeKey,
|
||||
VariesByCulture = propertyType.VariesByCulture(),
|
||||
VariesBySegment = propertyType.VariesBySegment(),
|
||||
Validation = new PropertyTypeValidation()
|
||||
{
|
||||
Mandatory = propertyType.Mandatory,
|
||||
MandatoryMessage = propertyType.ValidationRegExp,
|
||||
RegularExpression = propertyType.ValidationRegExp,
|
||||
RegularExpressionMessage = propertyType.ValidationRegExpMessage,
|
||||
},
|
||||
Appearance = new PropertyTypeAppearance() { LabelOnTop = propertyType.LabelOnTop, }
|
||||
};
|
||||
tempPropertyList.Add(propertyModel);
|
||||
}
|
||||
|
||||
model.Properties = tempPropertyList.AsEnumerable();
|
||||
return model;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.ContentEditing;
|
||||
using Umbraco.Cms.Core.Models.ContentTypeEditing;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Services.ContentTypeEditing;
|
||||
using Umbraco.Cms.Tests.Common.Builders;
|
||||
using Umbraco.Cms.Tests.Common.TestHelpers;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.Testing;
|
||||
|
||||
public abstract class UmbracoIntegrationTestWithMediaEditing : UmbracoIntegrationTest
|
||||
{
|
||||
protected IMediaTypeService MediaTypeService => GetRequiredService<IMediaTypeService>();
|
||||
|
||||
protected IMediaEditingService MediaEditingService => GetRequiredService<IMediaEditingService>();
|
||||
|
||||
protected IMediaTypeEditingService MediaTypeEditingService => GetRequiredService<IMediaTypeEditingService>();
|
||||
|
||||
protected MediaCreateModel RootFolder { get; private set; }
|
||||
|
||||
protected int RootFolderId { get; private set; }
|
||||
|
||||
protected MediaCreateModel RootImage { get; private set; }
|
||||
|
||||
protected int RootImageId { get; private set; }
|
||||
|
||||
protected MediaCreateModel SubFolder1 { get; private set; }
|
||||
|
||||
protected int SubFolder1Id { get; private set; }
|
||||
|
||||
protected MediaCreateModel SubFolder2 { get; private set; }
|
||||
|
||||
protected int SubFolder2Id { get; private set; }
|
||||
|
||||
protected MediaCreateModel SubImage { get; private set; }
|
||||
|
||||
protected int SubImageId { get; private set; }
|
||||
|
||||
protected MediaCreateModel SubTestMedia { get; private set; }
|
||||
|
||||
protected int SubTestMediaId { get; private set; }
|
||||
|
||||
protected MediaCreateModel SubSubImage { get; private set; }
|
||||
|
||||
protected int SubSubImageId { get; private set; }
|
||||
|
||||
protected MediaCreateModel SubSubFile { get; private set; }
|
||||
|
||||
protected int SubSubFileId { get; private set; }
|
||||
|
||||
protected MediaTypeCreateModel CustomMediaTypeCreateModel { get; private set; }
|
||||
|
||||
protected IMediaType CustomMediaType { get; private set; }
|
||||
|
||||
[SetUp]
|
||||
public new void Setup() => CreateTestData();
|
||||
|
||||
protected async void CreateTestData()
|
||||
{
|
||||
CustomMediaTypeCreateModel = MediaTypeEditingBuilder.CreateMediaTypeWithOneProperty();
|
||||
var mediaTypeTestAttempt = await MediaTypeEditingService.CreateAsync(CustomMediaTypeCreateModel, Constants.Security.SuperUserKey);
|
||||
Assert.IsTrue(mediaTypeTestAttempt.Success);
|
||||
CustomMediaType = mediaTypeTestAttempt.Result;
|
||||
|
||||
// Gets all media types
|
||||
var folderMediaTypes = await MediaTypeEditingService.GetFolderMediaTypes(0, 10);
|
||||
var folderMediaType = folderMediaTypes.Items.FirstOrDefault(x => x.Alias == "Folder");
|
||||
var mediaTypes = MediaTypeService.GetAll();
|
||||
var mediaTypesList = mediaTypes.ToList();
|
||||
var imageMediaType = mediaTypesList.FirstOrDefault(x => x.Alias == "Image");
|
||||
|
||||
// Add CustomMediaType to FolderMediaType AllowedContentTypes
|
||||
var mediaTypeUpdateHelper = new MediaTypeUpdateHelper();
|
||||
var updateModel = mediaTypeUpdateHelper.CreateMediaTypeUpdateModel(folderMediaType);
|
||||
var folderMediaTypeAllowedContentTypes = updateModel.AllowedContentTypes.ToList();
|
||||
folderMediaTypeAllowedContentTypes.Add(new ContentTypeSort(key: mediaTypeTestAttempt.Result.Key, sortOrder: folderMediaTypeAllowedContentTypes.Count, alias: CustomMediaTypeCreateModel.Alias));
|
||||
updateModel.AllowedContentTypes = folderMediaTypeAllowedContentTypes;
|
||||
var updatedFolderMediaTypeAttempt = MediaTypeEditingService.UpdateAsync(folderMediaType, updateModel, Constants.Security.SuperUserKey);
|
||||
Assert.IsTrue(updatedFolderMediaTypeAttempt.Result.Success);
|
||||
|
||||
// Create and Save RootFolder
|
||||
RootFolder = MediaEditingBuilder.CreateSimpleMedia(folderMediaType.Key, "RootFolder", null);
|
||||
var rootFolderAttempt = await MediaEditingService.CreateAsync(RootFolder, Constants.Security.SuperUserKey);
|
||||
Assert.IsTrue(rootFolderAttempt.Success);
|
||||
if (rootFolderAttempt.Result.Content != null)
|
||||
{
|
||||
RootFolderId = rootFolderAttempt.Result.Content.Id;
|
||||
}
|
||||
|
||||
// Create and Save RootImage
|
||||
RootImage = MediaEditingBuilder.CreateSimpleMedia(imageMediaType.Key, "RootImage", null);
|
||||
var rootImageAttempt = await MediaEditingService.CreateAsync(RootImage, Constants.Security.SuperUserKey);
|
||||
Assert.IsTrue(rootImageAttempt.Success);
|
||||
if (rootImageAttempt.Result.Content != null)
|
||||
{
|
||||
RootImageId = rootImageAttempt.Result.Content.Id;
|
||||
}
|
||||
|
||||
// Create and Save SubFolder1
|
||||
SubFolder1 = MediaEditingBuilder.CreateSimpleMedia(folderMediaType.Key, "SubFolder1", RootFolder.Key);
|
||||
var subFolder1Attempt = await MediaEditingService.CreateAsync(SubFolder1, Constants.Security.SuperUserKey);
|
||||
Assert.IsTrue(subFolder1Attempt.Success);
|
||||
if (subFolder1Attempt.Result.Content != null)
|
||||
{
|
||||
SubFolder1Id = subFolder1Attempt.Result.Content.Id;
|
||||
}
|
||||
|
||||
// Create and Save SubFolder2
|
||||
SubFolder2 = MediaEditingBuilder.CreateSimpleMedia(folderMediaType.Key, "SubFolder2", RootFolder.Key);
|
||||
var subFolder2Attempt = await MediaEditingService.CreateAsync(SubFolder2, Constants.Security.SuperUserKey);
|
||||
Assert.IsTrue(subFolder2Attempt.Success);
|
||||
if (subFolder2Attempt.Result.Content != null)
|
||||
{
|
||||
SubFolder2Id = subFolder2Attempt.Result.Content.Id;
|
||||
}
|
||||
|
||||
// Create and Save SubImage
|
||||
SubImage = MediaEditingBuilder.CreateSimpleMedia(imageMediaType.Key, "SubImage", RootFolder.Key);
|
||||
var subImageAttempt = await MediaEditingService.CreateAsync(SubImage, Constants.Security.SuperUserKey);
|
||||
Assert.IsTrue(subImageAttempt.Success);
|
||||
if (subImageAttempt.Result.Content != null)
|
||||
{
|
||||
SubImageId = subImageAttempt.Result.Content.Id;
|
||||
}
|
||||
|
||||
// Create and Save SubTestMedia
|
||||
SubTestMedia = MediaEditingBuilder.CreateMediaWithAProperty(mediaTypeTestAttempt.Result.Key, "SubTestMedia", RootFolder.Key, "testProperty", "This is a test");
|
||||
var subTestMediaAttempt = await MediaEditingService.CreateAsync(SubTestMedia, Constants.Security.SuperUserKey);
|
||||
Assert.IsTrue(subTestMediaAttempt.Success);
|
||||
if (subTestMediaAttempt.Result.Content != null)
|
||||
{
|
||||
SubTestMediaId = subTestMediaAttempt.Result.Content.Id;
|
||||
}
|
||||
|
||||
// Create and Save SubSubImage
|
||||
SubSubImage = MediaEditingBuilder.CreateSimpleMedia(imageMediaType.Key, "SubSubImage", SubFolder1.Key);
|
||||
var subSubImageAttempt = await MediaEditingService.CreateAsync(SubSubImage, Constants.Security.SuperUserKey);
|
||||
Assert.IsTrue(subSubImageAttempt.Success);
|
||||
if (subSubImageAttempt.Result.Content != null)
|
||||
{
|
||||
SubSubImageId = subSubImageAttempt.Result.Content.Id;
|
||||
}
|
||||
|
||||
// Create and Save SubSubFile
|
||||
SubSubFile = MediaEditingBuilder.CreateSimpleMedia(imageMediaType.Key, "SubSubFile", SubFolder1.Key);
|
||||
var subSubFileAttempt = await MediaEditingService.CreateAsync(SubSubFile, Constants.Security.SuperUserKey);
|
||||
Assert.IsTrue(subSubFileAttempt.Success);
|
||||
if (subSubFileAttempt.Result.Content != null)
|
||||
{
|
||||
SubSubFileId = subSubFileAttempt.Result.Content.Id;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -48,12 +48,12 @@ public class DocumentHybridCacheDocumentTypeTests : UmbracoIntegrationTestWithCo
|
||||
public async Task Content_Gets_Removed_When_DocumentType_Is_Deleted()
|
||||
{
|
||||
// Load into cache
|
||||
var textpage = await PublishedContentHybridCache.GetByIdAsync(Textpage.Key.Value, preview: true);
|
||||
Assert.IsNotNull(textpage);
|
||||
var textPage = await PublishedContentHybridCache.GetByIdAsync(Textpage.Key.Value, preview: true);
|
||||
Assert.IsNotNull(textPage);
|
||||
|
||||
await ContentTypeService.DeleteAsync(textpage.ContentType.Key, Constants.Security.SuperUserKey);
|
||||
await ContentTypeService.DeleteAsync(textPage.ContentType.Key, Constants.Security.SuperUserKey);
|
||||
|
||||
var textpageAgain = await PublishedContentHybridCache.GetByIdAsync(Textpage.Key.Value, preview: true);
|
||||
Assert.IsNull(textpageAgain);
|
||||
var textPageAgain = await PublishedContentHybridCache.GetByIdAsync(Textpage.Key.Value, preview: true);
|
||||
Assert.IsNull(textPageAgain);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ using Umbraco.Cms.Infrastructure.HybridCache;
|
||||
using Umbraco.Cms.Infrastructure.HybridCache.Factories;
|
||||
using Umbraco.Cms.Infrastructure.HybridCache.Persistence;
|
||||
using Umbraco.Cms.Infrastructure.HybridCache.SeedKeyProviders.Document;
|
||||
using Umbraco.Cms.Infrastructure.HybridCache.Serialization;
|
||||
using Umbraco.Cms.Infrastructure.HybridCache.Services;
|
||||
using Umbraco.Cms.Tests.Common.Testing;
|
||||
using Umbraco.Cms.Tests.Integration.Testing;
|
||||
@@ -86,7 +87,7 @@ public class DocumentHybridCacheMockTests : UmbracoIntegrationTestWithContent
|
||||
_mockedNucacheRepository.Setup(r => r.GetContentSourceAsync(It.IsAny<Guid>(), false))
|
||||
.ReturnsAsync(publishedTestCacheNode);
|
||||
|
||||
_mockedNucacheRepository.Setup(r => r.GetContentByContentTypeKey(It.IsAny<IReadOnlyCollection<Guid>>())).Returns(
|
||||
_mockedNucacheRepository.Setup(r => r.GetContentByContentTypeKey(It.IsAny<IReadOnlyCollection<Guid>>(), ContentCacheDataSerializerEntityType.Document)).Returns(
|
||||
new List<ContentCacheNode>()
|
||||
{
|
||||
draftTestCacheNode,
|
||||
|
||||
@@ -9,7 +9,6 @@ using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Services.ContentTypeEditing;
|
||||
using Umbraco.Cms.Core.Services.OperationStatus;
|
||||
using Umbraco.Cms.Tests.Common.Builders;
|
||||
using Umbraco.Cms.Tests.Common.Builders.Extensions;
|
||||
using Umbraco.Cms.Tests.Common.Testing;
|
||||
using Umbraco.Cms.Tests.Integration.Testing;
|
||||
|
||||
@@ -104,35 +103,13 @@ public class DocumentHybridCachePropertyTest : UmbracoIntegrationTest
|
||||
|
||||
private async Task<IContent> CreateContentPickerDocument(Guid templateKey, Guid textPageKey)
|
||||
{
|
||||
var builder = new ContentTypeEditingBuilder();
|
||||
var pickerContentType = builder
|
||||
.WithAlias("test")
|
||||
.WithName("TestName")
|
||||
.WithAllowAtRoot(true)
|
||||
.AddAllowedTemplateKeys([templateKey])
|
||||
.AddPropertyGroup()
|
||||
.WithName("Content")
|
||||
.Done()
|
||||
.AddPropertyType()
|
||||
.WithAlias("contentPicker")
|
||||
.WithName("Content Picker")
|
||||
.WithDataTypeKey(Constants.DataTypes.Guids.ContentPickerGuid)
|
||||
.WithSortOrder(16)
|
||||
.Done()
|
||||
.Build();
|
||||
|
||||
var pickerContentType = ContentTypeEditingBuilder.CreateContentTypeWithContentPicker(templateKey: templateKey);
|
||||
await ContentTypeEditingService.CreateAsync(pickerContentType, Constants.Security.SuperUserKey);
|
||||
|
||||
|
||||
var createOtherModel = new ContentCreateModel
|
||||
{
|
||||
ContentTypeKey = pickerContentType.Key.Value,
|
||||
ParentKey = Constants.System.RootKey,
|
||||
InvariantName = "Test Create",
|
||||
InvariantProperties = new[] { new PropertyValueModel { Alias = "contentPicker", Value = textPageKey }, },
|
||||
};
|
||||
|
||||
var createOtherModel = ContentEditingBuilder.CreateContentWithOneInvariantProperty(pickerContentType.Key.Value,
|
||||
"Test Create", "contentPicker", textPageKey);
|
||||
var result = await ContentEditingService.CreateAsync(createOtherModel, Constants.Security.SuperUserKey);
|
||||
|
||||
Assert.IsTrue(result.Success);
|
||||
Assert.AreEqual(ContentEditingOperationStatus.Success, result.Status);
|
||||
|
||||
@@ -145,6 +122,7 @@ public class DocumentHybridCachePropertyTest : UmbracoIntegrationTest
|
||||
},
|
||||
Constants.Security.SuperUserKey);
|
||||
|
||||
Assert.IsTrue(publishResult.Success);
|
||||
return result.Result.Content;
|
||||
}
|
||||
|
||||
@@ -153,19 +131,11 @@ public class DocumentHybridCachePropertyTest : UmbracoIntegrationTest
|
||||
var textContentType = ContentTypeEditingBuilder.CreateTextPageContentType(defaultTemplateKey: templateKey);
|
||||
await ContentTypeEditingService.CreateAsync(textContentType, Constants.Security.SuperUserKey);
|
||||
|
||||
var createModel = new ContentCreateModel
|
||||
{
|
||||
ContentTypeKey = textContentType.Key.Value,
|
||||
ParentKey = Constants.System.RootKey,
|
||||
InvariantName = "Root Create",
|
||||
InvariantProperties = new[]
|
||||
{
|
||||
new PropertyValueModel { Alias = "title", Value = "The title value" },
|
||||
new PropertyValueModel { Alias = "bodyText", Value = "The body text" }
|
||||
},
|
||||
};
|
||||
var contentCreateModel = ContentEditingBuilder.CreateContentWithTwoInvariantProperties(
|
||||
textContentType.Key.Value, "Root Create", "title", "The title value", "bodyText", "The body text",
|
||||
Constants.System.RootKey);
|
||||
|
||||
var createResult = await ContentEditingService.CreateAsync(createModel, Constants.Security.SuperUserKey);
|
||||
var createResult = await ContentEditingService.CreateAsync(contentCreateModel, Constants.Security.SuperUserKey);
|
||||
Assert.IsTrue(createResult.Success);
|
||||
|
||||
var publishResult = await ContentPublishingService.PublishAsync(
|
||||
|
||||
@@ -18,12 +18,12 @@ public class DocumentHybridCacheScopeTests : UmbracoIntegrationTestWithContentEd
|
||||
|
||||
private IContentPublishingService ContentPublishingService => GetRequiredService<IContentPublishingService>();
|
||||
|
||||
private ICoreScopeProvider ICoreScopeProvider => GetRequiredService<ICoreScopeProvider>();
|
||||
private ICoreScopeProvider CoreScopeProvider => GetRequiredService<ICoreScopeProvider>();
|
||||
|
||||
[Test]
|
||||
public async Task Can_Get_Correct_Content_After_Rollback_With_Id()
|
||||
{
|
||||
using (ICoreScopeProvider.CreateCoreScope())
|
||||
using (CoreScopeProvider.CreateCoreScope())
|
||||
{
|
||||
await ContentPublishingService.PublishAsync(Textpage.Key.Value, CultureAndSchedule, Constants.Security.SuperUserKey);
|
||||
}
|
||||
@@ -38,7 +38,7 @@ public class DocumentHybridCacheScopeTests : UmbracoIntegrationTestWithContentEd
|
||||
[Test]
|
||||
public async Task Can_Get_Correct_Content_After_Rollback_With_Key()
|
||||
{
|
||||
using (ICoreScopeProvider.CreateCoreScope())
|
||||
using (CoreScopeProvider.CreateCoreScope())
|
||||
{
|
||||
await ContentPublishingService.PublishAsync(Textpage.Key.Value, CultureAndSchedule, Constants.Security.SuperUserKey);
|
||||
}
|
||||
@@ -53,7 +53,7 @@ public class DocumentHybridCacheScopeTests : UmbracoIntegrationTestWithContentEd
|
||||
[Test]
|
||||
public async Task Can_Get_Document_After_Scope_Complete_With_Id()
|
||||
{
|
||||
using (var scope = ICoreScopeProvider.CreateCoreScope())
|
||||
using (var scope = CoreScopeProvider.CreateCoreScope())
|
||||
{
|
||||
await ContentPublishingService.PublishAsync(Textpage.Key.Value, CultureAndSchedule, Constants.Security.SuperUserKey);
|
||||
scope.Complete();
|
||||
@@ -69,7 +69,7 @@ public class DocumentHybridCacheScopeTests : UmbracoIntegrationTestWithContentEd
|
||||
[Test]
|
||||
public async Task Can_Get_Document_After_Scope_Completes_With_Key()
|
||||
{
|
||||
using (var scope = ICoreScopeProvider.CreateCoreScope())
|
||||
using (var scope = CoreScopeProvider.CreateCoreScope())
|
||||
{
|
||||
await ContentPublishingService.PublishAsync(Textpage.Key.Value, CultureAndSchedule, Constants.Security.SuperUserKey);
|
||||
scope.Complete();
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// using Umbraco.Cms.Core.Services.OperationStatus;
|
||||
// using Umbraco.Cms.Tests.Common.Testing;
|
||||
// using Umbraco.Cms.Tests.Integration.Testing;
|
||||
// FIXME
|
||||
// FIXME: This is fixed in the release branch, uncomment this once that's merged in.
|
||||
// namespace Umbraco.Cms.Tests.Integration.Umbraco.PublishedCache.HybridCache;
|
||||
//
|
||||
// [TestFixture]
|
||||
@@ -37,7 +37,6 @@
|
||||
// // Assert
|
||||
// Assert.AreEqual(updateContentResult.Status, ContentEditingOperationStatus.Success);
|
||||
// var textPageAfter = await PublishedContentHybridCache.GetByIdAsync(TextpageId, true);
|
||||
// // Should this not be null?
|
||||
// Assert.AreEqual(textPageAfter.TemplateId, null);
|
||||
// }
|
||||
// }
|
||||
|
||||
@@ -60,13 +60,7 @@ public class DocumentHybridCacheVariantsTests : UmbracoIntegrationTest
|
||||
Culture = _englishIsoCode,
|
||||
Name = "Updated English Name",
|
||||
Properties =
|
||||
new[]
|
||||
{
|
||||
new PropertyValueModel
|
||||
{
|
||||
Alias = _variantTitleAlias, Value = updatedVariantTitle
|
||||
}
|
||||
},
|
||||
new[] { new PropertyValueModel { Alias = _variantTitleAlias, Value = updatedVariantTitle } },
|
||||
},
|
||||
new VariantModel
|
||||
{
|
||||
@@ -74,16 +68,14 @@ public class DocumentHybridCacheVariantsTests : UmbracoIntegrationTest
|
||||
Name = "Updated Danish Name",
|
||||
Properties = new[]
|
||||
{
|
||||
new PropertyValueModel
|
||||
{
|
||||
Alias = _variantTitleAlias, Value = updatedVariantTitle
|
||||
},
|
||||
new PropertyValueModel { Alias = _variantTitleAlias, Value = updatedVariantTitle },
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
var result = await ContentEditingService.UpdateAsync(VariantPage.Key, updateModel, Constants.Security.SuperUserKey);
|
||||
var result =
|
||||
await ContentEditingService.UpdateAsync(VariantPage.Key, updateModel, Constants.Security.SuperUserKey);
|
||||
Assert.IsTrue(result.Success);
|
||||
|
||||
// Act
|
||||
@@ -116,10 +108,7 @@ public class DocumentHybridCacheVariantsTests : UmbracoIntegrationTest
|
||||
Name = "Updated English Name",
|
||||
Properties = new[]
|
||||
{
|
||||
new PropertyValueModel
|
||||
{
|
||||
Alias = _variantTitleAlias, Value = updatedVariantTitle
|
||||
},
|
||||
new PropertyValueModel { Alias = _variantTitleAlias, Value = updatedVariantTitle },
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -146,35 +135,18 @@ public class DocumentHybridCacheVariantsTests : UmbracoIntegrationTest
|
||||
.Build();
|
||||
await LanguageService.CreateAsync(language, Constants.Security.SuperUserKey);
|
||||
|
||||
var groupKey = Guid.NewGuid();
|
||||
var contentType = new ContentTypeEditingBuilder()
|
||||
.WithAlias("cultureVariationTest")
|
||||
.WithName("Culture Variation Test")
|
||||
.WithAllowAtRoot(true)
|
||||
.WithVariesByCulture(true)
|
||||
.AddPropertyType()
|
||||
.WithAlias(_variantTitleAlias)
|
||||
.WithName(_variantTitleName)
|
||||
.WithVariesByCulture(true)
|
||||
.WithContainerKey(groupKey)
|
||||
.Done()
|
||||
.AddPropertyType()
|
||||
.WithAlias(_invariantTitleAlias)
|
||||
.WithName(_invariantTitleName)
|
||||
.WithContainerKey(groupKey)
|
||||
.Done()
|
||||
.AddPropertyGroup()
|
||||
.WithName("content")
|
||||
.WithKey(groupKey)
|
||||
.Done()
|
||||
.Build();
|
||||
var contentType = ContentTypeEditingBuilder.CreateContentTypeWithTwoPropertiesOneVariantAndOneInvariant(
|
||||
"cultureVariationTest", "Culture Variation Test", _variantTitleAlias, _variantTitleName,
|
||||
_invariantTitleAlias, _invariantTitleName);
|
||||
var contentTypeAttempt = await ContentTypeEditingService.CreateAsync(contentType, Constants.Security.SuperUserKey);
|
||||
if (!contentTypeAttempt.Success)
|
||||
{
|
||||
throw new Exception("Failed to create content type");
|
||||
}
|
||||
|
||||
var rootContentCreateModel = ContentEditingBuilder.CreateContentWithTwoVariantProperties(contentTypeAttempt.Result.Key, "en-US", "da-DK", _variantTitleAlias, _variantTitleName);
|
||||
var rootContentCreateModel =
|
||||
ContentEditingBuilder.CreateContentWithTwoVariantProperties(contentTypeAttempt.Result.Key, "en-US", "da-DK",
|
||||
_variantTitleAlias, _variantTitleName);
|
||||
var result = await ContentEditingService.CreateAsync(rootContentCreateModel, Constants.Security.SuperUserKey);
|
||||
VariantPage = result.Result.Content;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.PublishedCache;
|
||||
using Umbraco.Cms.Core.Services.ContentTypeEditing;
|
||||
using Umbraco.Cms.Tests.Common.TestHelpers;
|
||||
using Umbraco.Cms.Tests.Common.Testing;
|
||||
using Umbraco.Cms.Tests.Integration.Testing;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.Umbraco.PublishedCache.HybridCache;
|
||||
|
||||
[TestFixture]
|
||||
[UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)]
|
||||
public class MediaHybridCacheMediaTypeTests : UmbracoIntegrationTestWithMediaEditing
|
||||
{
|
||||
private IPublishedMediaCache PublishedMediaHybridCache => GetRequiredService<IPublishedMediaCache>();
|
||||
|
||||
private new IMediaTypeEditingService MediaTypeEditingService => GetRequiredService<IMediaTypeEditingService>();
|
||||
|
||||
protected override void CustomTestSetup(IUmbracoBuilder builder) => builder.AddUmbracoHybridCache();
|
||||
|
||||
[Test]
|
||||
public async Task Cannot_Get_Property_From_Media_After_It_Is_Removed_From_MediaType_By_Id()
|
||||
{
|
||||
// Arrange
|
||||
var oldMedia = await PublishedMediaHybridCache.GetByIdAsync(SubTestMediaId);
|
||||
Assert.IsNotNull(oldMedia.Value("testProperty"));
|
||||
MediaTypeUpdateHelper mediaTypeUpdateHelper = new MediaTypeUpdateHelper();
|
||||
|
||||
// Act
|
||||
var updateModel = mediaTypeUpdateHelper.CreateMediaTypeUpdateModel(CustomMediaType);
|
||||
updateModel.Properties = [];
|
||||
updateModel.Containers = [];
|
||||
await MediaTypeEditingService.UpdateAsync(CustomMediaType, updateModel, Constants.Security.SuperUserKey);
|
||||
|
||||
// Assert
|
||||
var newMedia = await PublishedMediaHybridCache.GetByIdAsync(SubTestMediaId);
|
||||
Assert.IsNull(newMedia.Value("testProperty"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Cannot_Get_Property_From_Media_After_It_Is_Removed_From_MediaType_By_Key()
|
||||
{
|
||||
// Arrange
|
||||
var oldMedia = await PublishedMediaHybridCache.GetByIdAsync(SubTestMedia.Key.Value);
|
||||
Assert.IsNotNull(oldMedia.Value("testProperty"));
|
||||
MediaTypeUpdateHelper mediaTypeUpdateHelper = new MediaTypeUpdateHelper();
|
||||
|
||||
// Act
|
||||
var updateModel = mediaTypeUpdateHelper.CreateMediaTypeUpdateModel(CustomMediaType);
|
||||
updateModel.Properties = [];
|
||||
updateModel.Containers = [];
|
||||
await MediaTypeEditingService.UpdateAsync(CustomMediaType, updateModel, Constants.Security.SuperUserKey);
|
||||
|
||||
// Assert
|
||||
var newMedia = await PublishedMediaHybridCache.GetByIdAsync(SubTestMedia.Key.Value);
|
||||
Assert.IsNull(newMedia.Value("testProperty"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Media_Gets_Removed_When_MediaType_Is_Deleted()
|
||||
{
|
||||
// Arrange
|
||||
var media = await PublishedMediaHybridCache.GetByIdAsync(SubTestMedia.Key.Value);
|
||||
Assert.IsNotNull(media);
|
||||
|
||||
// Act
|
||||
await MediaTypeService.DeleteAsync(CustomMediaType.Key, Constants.Security.SuperUserKey);
|
||||
|
||||
// Assert
|
||||
var newMedia = await PublishedMediaHybridCache.GetByIdAsync(SubTestMedia.Key.Value);
|
||||
Assert.IsNull(newMedia);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.PublishedCache;
|
||||
using Umbraco.Cms.Core.Scoping;
|
||||
using Umbraco.Cms.Tests.Common.Testing;
|
||||
using Umbraco.Cms.Tests.Integration.Testing;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.Umbraco.PublishedCache.HybridCache;
|
||||
|
||||
[TestFixture]
|
||||
[UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)]
|
||||
public class MediaHybridCacheScopeTests : UmbracoIntegrationTestWithMediaEditing
|
||||
{
|
||||
protected override void CustomTestSetup(IUmbracoBuilder builder) => builder.AddUmbracoHybridCache();
|
||||
|
||||
private IPublishedMediaCache PublishedMediaHybridCache => GetRequiredService<IPublishedMediaCache>();
|
||||
|
||||
private ICoreScopeProvider CoreScopeProvider => GetRequiredService<ICoreScopeProvider>();
|
||||
|
||||
|
||||
[Test]
|
||||
public async Task Can_Get_Media_After_Delete_Was_Rolled_back_With_Id()
|
||||
{
|
||||
// Arrange
|
||||
using (CoreScopeProvider.CreateCoreScope())
|
||||
{
|
||||
await MediaEditingService.DeleteAsync(SubFolder1.Key.Value, Constants.Security.SuperUserKey);
|
||||
}
|
||||
|
||||
// Act
|
||||
var media = await PublishedMediaHybridCache.GetByIdAsync(SubFolder1Id);
|
||||
|
||||
// Assert
|
||||
// media should still be in cache, as we rolled scope back.
|
||||
Assert.IsNotNull(media);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Can_Get_Media_After_Delete_Was_Rolled_back_With_Key()
|
||||
{
|
||||
// Arrange
|
||||
using (CoreScopeProvider.CreateCoreScope())
|
||||
{
|
||||
await MediaEditingService.DeleteAsync(SubFolder1.Key.Value, Constants.Security.SuperUserKey);
|
||||
}
|
||||
|
||||
// Act
|
||||
var media = await PublishedMediaHybridCache.GetByIdAsync(SubFolder1.Key.Value);
|
||||
|
||||
// Assert
|
||||
// Media should still be in cache, as we rolled scope back.
|
||||
Assert.IsNotNull(media);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Can_Not_Get_Deleted_Media_After_Scope_Complete_With_Id()
|
||||
{
|
||||
// Arrange
|
||||
using (var scope = CoreScopeProvider.CreateCoreScope())
|
||||
{
|
||||
await MediaEditingService.DeleteAsync(SubFolder1.Key.Value, Constants.Security.SuperUserKey);
|
||||
scope.Complete();
|
||||
}
|
||||
|
||||
// Act
|
||||
var media = await PublishedMediaHybridCache.GetByIdAsync(SubFolder1Id);
|
||||
|
||||
// Assert
|
||||
// Media should not be in cache, as we completed the scope for delete.
|
||||
Assert.IsNull(media);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Can_Not_Get_Deleted_Media_After_Scope_Complete_With_Key()
|
||||
{
|
||||
// Arrange
|
||||
using (var scope = CoreScopeProvider.CreateCoreScope())
|
||||
{
|
||||
await MediaEditingService.DeleteAsync(SubFolder1.Key.Value, Constants.Security.SuperUserKey);
|
||||
scope.Complete();
|
||||
}
|
||||
|
||||
// Act
|
||||
var textPage = await PublishedMediaHybridCache.GetByIdAsync(SubFolder1.Key.Value);
|
||||
|
||||
// Assert
|
||||
// Media should not be in cache, as we completed the scope for delete.
|
||||
Assert.IsNull(textPage);
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,7 @@
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.ContentEditing;
|
||||
using Umbraco.Cms.Core.PublishedCache;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Web;
|
||||
using Umbraco.Cms.Tests.Common.Builders;
|
||||
using Umbraco.Cms.Tests.Common.Builders.Extensions;
|
||||
using Umbraco.Cms.Tests.Common.Testing;
|
||||
using Umbraco.Cms.Tests.Integration.Testing;
|
||||
|
||||
@@ -14,175 +9,161 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.PublishedCache.HybridCache;
|
||||
|
||||
[TestFixture]
|
||||
[UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)]
|
||||
public class MediaHybridCacheTests : UmbracoIntegrationTest
|
||||
public class MediaHybridCacheTests : UmbracoIntegrationTestWithMediaEditing
|
||||
{
|
||||
private IPublishedMediaCache PublishedMediaHybridCache => GetRequiredService<IPublishedMediaCache>();
|
||||
|
||||
private IUmbracoContextFactory UmbracoContextFactory => GetRequiredService<IUmbracoContextFactory>();
|
||||
|
||||
private IMediaTypeService MediaTypeService => GetRequiredService<IMediaTypeService>();
|
||||
|
||||
private IMediaEditingService MediaEditingService => GetRequiredService<IMediaEditingService>();
|
||||
|
||||
protected override void CustomTestSetup(IUmbracoBuilder builder) => builder.AddUmbracoHybridCache();
|
||||
|
||||
// TODO: make test with MediaWithCrops
|
||||
|
||||
// Media with crops
|
||||
[Test]
|
||||
public async Task Can_Get_Media_By_Key()
|
||||
public async Task Can_Get_Root_Media_By_Id()
|
||||
{
|
||||
// Arrange
|
||||
var newMediaType = new MediaTypeBuilder()
|
||||
.WithAlias("album")
|
||||
.WithName("Album")
|
||||
.Build();
|
||||
|
||||
newMediaType.AllowedAsRoot = true;
|
||||
MediaTypeService.Save(newMediaType);
|
||||
|
||||
var createModel = new MediaCreateModel
|
||||
{
|
||||
ContentTypeKey = newMediaType.Key,
|
||||
ParentKey = Constants.System.RootKey,
|
||||
InvariantName = "Image",
|
||||
};
|
||||
|
||||
var result = await MediaEditingService.CreateAsync(createModel, Constants.Security.SuperUserKey);
|
||||
Assert.IsTrue(result.Success);
|
||||
|
||||
// Act
|
||||
var media = await PublishedMediaHybridCache.GetByKeyAsync(result.Result.Content.Key);
|
||||
var media = await PublishedMediaHybridCache.GetByIdAsync(RootFolderId);
|
||||
|
||||
// Assert
|
||||
Assert.IsNotNull(media);
|
||||
Assert.AreEqual("Image", media.Name);
|
||||
Assert.AreEqual(newMediaType.Key, media.ContentType.Key);
|
||||
Assert.AreEqual("RootFolder", media.Name);
|
||||
Assert.AreEqual(RootFolder.ContentTypeKey, media.ContentType.Key);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Can_Get_Media_By_Id()
|
||||
public async Task Can_Get_Root_Media_By_Key()
|
||||
{
|
||||
// Arrange
|
||||
var newMediaType = new MediaTypeBuilder()
|
||||
.WithAlias("album")
|
||||
.WithName("Album")
|
||||
.Build();
|
||||
|
||||
newMediaType.AllowedAsRoot = true;
|
||||
MediaTypeService.Save(newMediaType);
|
||||
|
||||
var createModel = new MediaCreateModel
|
||||
{
|
||||
ContentTypeKey = newMediaType.Key,
|
||||
ParentKey = Constants.System.RootKey,
|
||||
InvariantName = "Image",
|
||||
};
|
||||
|
||||
var result = await MediaEditingService.CreateAsync(createModel, Constants.Security.SuperUserKey);
|
||||
Assert.IsTrue(result.Success);
|
||||
|
||||
// Act
|
||||
var media = await PublishedMediaHybridCache.GetByIdAsync(result.Result.Content.Id);
|
||||
var media = await PublishedMediaHybridCache.GetByIdAsync(RootFolder.Key.Value);
|
||||
|
||||
// Assert
|
||||
Assert.IsNotNull(media);
|
||||
Assert.AreEqual("Image", media.Name);
|
||||
Assert.AreEqual(newMediaType.Key, media.ContentType.Key);
|
||||
Assert.AreEqual("RootFolder", media.Name);
|
||||
Assert.AreEqual(RootFolder.ContentTypeKey, media.ContentType.Key);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Cannot_Get_Non_Existing_Media_By_Key()
|
||||
public async Task Can_Get_Child_Media_By_Id()
|
||||
{
|
||||
// Act
|
||||
var media = await PublishedMediaHybridCache.GetByKeyAsync(Guid.NewGuid());
|
||||
var media = await PublishedMediaHybridCache.GetByIdAsync(SubImageId);
|
||||
|
||||
// Assert
|
||||
Assert.IsNull(media);
|
||||
Assert.IsNotNull(media);
|
||||
Assert.AreEqual("SubImage", media.Name);
|
||||
Assert.AreEqual(SubImage.ContentTypeKey, media.ContentType.Key);
|
||||
Assert.AreEqual(SubImage.ParentKey, RootFolder.Key);
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public async Task Can_Get_Child_Media_By_Key()
|
||||
{
|
||||
var media = await PublishedMediaHybridCache.GetByIdAsync(SubImage.Key.Value);
|
||||
|
||||
// Assert
|
||||
Assert.IsNotNull(media);
|
||||
Assert.AreEqual("SubImage", media.Name);
|
||||
Assert.AreEqual(SubImage.ContentTypeKey, media.ContentType.Key);
|
||||
Assert.AreEqual(SubImage.ParentKey, RootFolder.Key);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Cannot_Get_Non_Existing_Media_By_Id()
|
||||
{
|
||||
// Act
|
||||
var media = await PublishedMediaHybridCache.GetByIdAsync(124214);
|
||||
const int nonExistingId = 124214;
|
||||
var media = await PublishedMediaHybridCache.GetByIdAsync(nonExistingId);
|
||||
|
||||
// Assert
|
||||
Assert.IsNull(media);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Can_Get_Media_Property_By_Key()
|
||||
public async Task Cannot_Get_Non_Existing_Media_By_Key()
|
||||
{
|
||||
// Arrange
|
||||
var media = await CreateMedia();
|
||||
|
||||
// Act
|
||||
var publishedMedia = await PublishedMediaHybridCache.GetByKeyAsync(media.Key);
|
||||
|
||||
UmbracoContextFactory.EnsureUmbracoContext();
|
||||
var media = await PublishedMediaHybridCache.GetByIdAsync(Guid.NewGuid());
|
||||
|
||||
// Assert
|
||||
Assert.IsNotNull(media);
|
||||
Assert.AreEqual("Image", media.Name);
|
||||
Assert.AreEqual("NewTitle", publishedMedia.Value("title"));
|
||||
Assert.IsNull(media);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Can_Get_Media_Property_By_Id()
|
||||
{
|
||||
// Arrange
|
||||
var media = await CreateMedia();
|
||||
|
||||
// Act
|
||||
var publishedMedia = await PublishedMediaHybridCache.GetByKeyAsync(media.Key);
|
||||
|
||||
UmbracoContextFactory.EnsureUmbracoContext();
|
||||
var media = await PublishedMediaHybridCache.GetByIdAsync(SubTestMediaId);
|
||||
|
||||
// Assert
|
||||
Assert.IsNotNull(publishedMedia);
|
||||
Assert.AreEqual("Image", publishedMedia.Name);
|
||||
Assert.AreEqual("NewTitle", publishedMedia.Value("title"));
|
||||
Assert.IsNotNull(media);
|
||||
Assert.AreEqual("SubTestMedia", media.Name);
|
||||
Assert.AreEqual("This is a test", media.Value("testProperty"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Can_Get_Updated_Media()
|
||||
public async Task Can_Get_Media_Property_By_Key()
|
||||
{
|
||||
// Arrange
|
||||
var media = await CreateMedia();
|
||||
await PublishedMediaHybridCache.GetByIdAsync(media.Id);
|
||||
|
||||
// Act
|
||||
var updateModel = new MediaUpdateModel()
|
||||
{
|
||||
InvariantName = "Update name",
|
||||
InvariantProperties = new List<PropertyValueModel>()
|
||||
{
|
||||
new()
|
||||
{
|
||||
Alias = "title",
|
||||
Value = "Updated Title"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var updateAttempt = await MediaEditingService.UpdateAsync(media.Key, updateModel, Constants.Security.SuperUserKey);
|
||||
Assert.IsTrue(updateAttempt.Success);
|
||||
var publishedMedia = await PublishedMediaHybridCache.GetByIdAsync(media.Id);
|
||||
UmbracoContextFactory.EnsureUmbracoContext();
|
||||
var media = await PublishedMediaHybridCache.GetByIdAsync(SubTestMedia.Key.Value);
|
||||
|
||||
// Assert
|
||||
Assert.IsNotNull(publishedMedia);
|
||||
Assert.AreEqual("Update name", publishedMedia.Name);
|
||||
Assert.AreEqual("Updated Title", publishedMedia.Value("title"));
|
||||
Assert.IsNotNull(media);
|
||||
Assert.AreEqual("SubTestMedia", media.Name);
|
||||
Assert.AreEqual("This is a test", media.Value("testProperty"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Can_Get_Updated_Media_By_Id()
|
||||
{
|
||||
// Arrange
|
||||
const string newName = "NewImageName";
|
||||
var media = await PublishedMediaHybridCache.GetByIdAsync(SubImageId);
|
||||
Assert.AreEqual(media.Name, "SubImage");
|
||||
|
||||
var mediaUpdateModel = new MediaUpdateModel
|
||||
{
|
||||
InvariantName = newName,
|
||||
InvariantProperties = SubImage.InvariantProperties,
|
||||
Variants = SubImage.Variants,
|
||||
};
|
||||
|
||||
// Act
|
||||
await MediaEditingService.UpdateAsync(SubImage.Key.Value, mediaUpdateModel, Constants.Security.SuperUserKey);
|
||||
var updatedMedia = await PublishedMediaHybridCache.GetByIdAsync(SubImageId);
|
||||
|
||||
// Assert
|
||||
Assert.IsNotNull(updatedMedia);
|
||||
Assert.AreEqual(newName, updatedMedia.Name);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Can_Get_Updated_Media_By_Key()
|
||||
{
|
||||
// Arrange
|
||||
const string newName = "NewImageName";
|
||||
var media = await PublishedMediaHybridCache.GetByIdAsync(SubImage.Key.Value);
|
||||
Assert.AreEqual(media.Name, "SubImage");
|
||||
|
||||
var mediaUpdateModel = new MediaUpdateModel
|
||||
{
|
||||
InvariantName = newName,
|
||||
InvariantProperties = SubImage.InvariantProperties,
|
||||
Variants = SubImage.Variants,
|
||||
};
|
||||
|
||||
// Act
|
||||
await MediaEditingService.UpdateAsync(SubImage.Key.Value, mediaUpdateModel, Constants.Security.SuperUserKey);
|
||||
var updatedMedia = await PublishedMediaHybridCache.GetByIdAsync(SubImageId);
|
||||
|
||||
// Assert
|
||||
Assert.IsNotNull(updatedMedia);
|
||||
Assert.AreEqual(newName, updatedMedia.Name);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Cannot_Get_Deleted_Media_By_Id()
|
||||
{
|
||||
// Arrange
|
||||
var media = await CreateMedia();
|
||||
var publishedMedia = await PublishedMediaHybridCache.GetByIdAsync(media.Id);
|
||||
Assert.IsNotNull(publishedMedia);
|
||||
var media = await PublishedMediaHybridCache.GetByIdAsync(SubImageId);
|
||||
Assert.IsNotNull(media);
|
||||
|
||||
await MediaEditingService.DeleteAsync(media.Key, Constants.Security.SuperUserKey);
|
||||
|
||||
@@ -197,42 +178,16 @@ public class MediaHybridCacheTests : UmbracoIntegrationTest
|
||||
public async Task Cannot_Get_Deleted_Media_By_Key()
|
||||
{
|
||||
// Arrange
|
||||
var media = await CreateMedia();
|
||||
var publishedMedia = await PublishedMediaHybridCache.GetByKeyAsync(media.Key);
|
||||
Assert.IsNotNull(publishedMedia);
|
||||
var media = await PublishedMediaHybridCache.GetByIdAsync(SubImage.Key.Value);
|
||||
|
||||
Assert.IsNotNull(media);
|
||||
|
||||
await MediaEditingService.DeleteAsync(media.Key, Constants.Security.SuperUserKey);
|
||||
|
||||
// Act
|
||||
var deletedMedia = await PublishedMediaHybridCache.GetByKeyAsync(media.Key);
|
||||
var deletedMedia = await PublishedMediaHybridCache.GetByIdAsync(media.Key);
|
||||
|
||||
// Assert
|
||||
Assert.IsNull(deletedMedia);
|
||||
}
|
||||
|
||||
private async Task<IMedia> CreateMedia()
|
||||
{
|
||||
IMediaType mediaType = MediaTypeBuilder.CreateSimpleMediaType("test", "Test");
|
||||
mediaType.AllowedAsRoot = true;
|
||||
MediaTypeService.Save(mediaType);
|
||||
|
||||
var createModel = new MediaCreateModel
|
||||
{
|
||||
ContentTypeKey = mediaType.Key,
|
||||
ParentKey = Constants.System.RootKey,
|
||||
InvariantName = "Image",
|
||||
InvariantProperties = new List<PropertyValueModel>()
|
||||
{
|
||||
new()
|
||||
{
|
||||
Alias = "title",
|
||||
Value = "NewTitle"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var result = await MediaEditingService.CreateAsync(createModel, Constants.Security.SuperUserKey);
|
||||
Assert.IsTrue(result.Success);
|
||||
return result.Result.Content;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,7 +61,8 @@ public class ContentTypeTests
|
||||
|
||||
private ContentTypeSort BuildContentTypeSort()
|
||||
{
|
||||
var builder = new ContentTypeSortBuilder();
|
||||
ContentTypeBuilder contentTypeBuilder = new ContentTypeBuilder();
|
||||
var builder = new ContentTypeSortBuilder<ContentTypeBuilder>(contentTypeBuilder);
|
||||
return builder
|
||||
.WithKey(new Guid("4CAE063E-0BE1-4972-B10C-A3D9BB7DE856"))
|
||||
.WithSortOrder(4)
|
||||
|
||||
Reference in New Issue
Block a user