diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md
index ac5f185..fde7893 100644
--- a/.github/copilot-instructions.md
+++ b/.github/copilot-instructions.md
@@ -11,10 +11,11 @@
- Prefer var over explicit types.
- Employ dependency injection using the built-in DI container.
- Handle exceptions gracefully and use `Microsoft.Extensions.Logging` for logging.
+- This is a Xperience By Kentico library, and as such should leverage built in api as much as possible.
## Testing Guidelnes
-- Use the AAA paattern (Arrange, Act, Assert)
+- Use the AAA pattern (Arrange, Act, Assert)
- Avoid infrastructure dependencies.
- Name tests clearly.
- Write minimally passing tests.
@@ -22,8 +23,4 @@
- Avoid logic in tests.
- Prefer helper methods for setup and teardown.
- Avoid multiple acts in a single test.
-- Write unit tests using **NUnit** and aim for high code coverage.
-
-## Project-specific instructions
-
-- Utilize Xperience by Kentico API for database interactions if applicable.
+- Write unit tests using **NUnit** and aim for high code coverage.
\ No newline at end of file
diff --git a/Directory.Packages.props b/Directory.Packages.props
index f72faa7..2ec4bfd 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -6,7 +6,7 @@
true
-
+
@@ -15,9 +15,9 @@
-
+
-
+
diff --git a/src/XperienceCommunity.DataRepository/BaseRepository.cs b/src/XperienceCommunity.DataRepository/BaseRepository.cs
index fdfbc94..caeb3b0 100644
--- a/src/XperienceCommunity.DataRepository/BaseRepository.cs
+++ b/src/XperienceCommunity.DataRepository/BaseRepository.cs
@@ -104,7 +104,6 @@ protected async Task> ExecutePageQuery(ContentItemQueryBuilder
return result;
}
-
if (dependencyFunc is not null)
{
cs.CacheDependency = dependencyFunc.Invoke();
diff --git a/src/XperienceCommunity.DataRepository/ContentTypeRepository.cs b/src/XperienceCommunity.DataRepository/ContentTypeRepository.cs
index bb4222a..e2fa463 100644
--- a/src/XperienceCommunity.DataRepository/ContentTypeRepository.cs
+++ b/src/XperienceCommunity.DataRepository/ContentTypeRepository.cs
@@ -42,9 +42,10 @@ public async Task> GetAllAsync(IEnumerable nodeGuid,
var builder = new ContentItemQueryBuilder();
builder.ForContentType(config => config
- .When(maxLinkedItems > 0, linkOptions => linkOptions.WithLinkedItems(maxLinkedItems))
- .Where(where => where.WhereIn(nameof(IContentItemFieldsSource.SystemFields.ContentItemGUID),
- guidList))).When(!string.IsNullOrEmpty(languageName), lang => lang.InLanguage(languageName));
+ .WithLinkedItemsAndWebPageData(maxLinkedItems)
+ .Where(where => where.WhereIn(nameof(IContentItemFieldsSource.SystemFields.ContentItemGUID),
+ guidList)))
+ .WithLanguage(languageName);
var result = await ExecuteContentQuery(builder, dependencyFunc,
cancellationToken, CachePrefix, nameof(GetAllAsync), guidList, maxLinkedItems);
@@ -69,9 +70,9 @@ public async Task> GetAllAsync(IEnumerable itemIds, st
var builder = new ContentItemQueryBuilder();
builder.ForContentType(config => config
- .When(maxLinkedItems > 0, linkOptions => linkOptions.WithLinkedItems(maxLinkedItems))
+ .WithLinkedItemsAndWebPageData(maxLinkedItems)
.Where(where => where.WhereIn(nameof(IContentItemFieldsSource.SystemFields.ContentItemID), idList)))
- .When(!string.IsNullOrEmpty(languageName), lang => lang.InLanguage(languageName));
+ .WithLanguage(languageName);
var result = await ExecuteContentQuery(builder, dependencyFunc,
cancellationToken, CachePrefix, nameof(GetAllAsync), idList, maxLinkedItems);
@@ -88,8 +89,9 @@ public async Task> GetAllAsync(string? languageName, int ma
var builder = new ContentItemQueryBuilder();
builder.ForContentType(config =>
- config.When(maxLinkedItems > 0, linkOptions => linkOptions.WithLinkedItems(maxLinkedItems)))
- .When(!string.IsNullOrEmpty(languageName), lang => lang.InLanguage(languageName));
+ config
+ .WithLinkedItemsAndWebPageData(maxLinkedItems))
+ .WithLanguage(languageName);
var result = await ExecuteContentQuery(builder, dependencyFunc,
cancellationToken, CachePrefix, nameof(GetAllAsync), contentType, maxLinkedItems);
@@ -108,11 +110,10 @@ public async Task> GetAllBySchema(string? language
var builder = new ContentItemQueryBuilder();
builder.ForContentTypes(parameters => parameters
- .When(maxLinkedItems > 0, linkItemOptions => linkItemOptions.WithLinkedItems(maxLinkedItems))
+ .WithLinkedItemsAndWebPageData(maxLinkedItems)
.OfReusableSchema(schemaName)
.WithContentTypeFields())
- .When(!string.IsNullOrEmpty(languageName),
- lang => lang.InLanguage(languageName));
+ .WithLanguage(languageName);
var result = await ExecuteContentQuery(builder,
() => CacheHelper.GetCacheDependency($"{schemaName}|all"),
@@ -130,11 +131,11 @@ public async Task> GetAllBySchema(string? language
var builder = new ContentItemQueryBuilder();
builder.ForContentType(config => config
- .When(maxLinkedItems > 0, linkOptions => linkOptions.WithLinkedItems(maxLinkedItems))
+ .WithLinkedItemsAndWebPageData(maxLinkedItems)
.Where(where =>
where.WhereEquals(nameof(IContentItemFieldsSource.SystemFields.ContentItemGUID), itemGuid))
.TopN(1))
- .When(!string.IsNullOrEmpty(languageName), lang => lang.InLanguage(languageName));
+ .WithLanguage(languageName);
var result = await ExecuteContentQuery(builder, dependencyFunc,
cancellationToken, CachePrefix, nameof(GetByIdAsync), itemGuid, maxLinkedItems);
@@ -150,11 +151,11 @@ public async Task> GetAllBySchema(string? language
var builder = new ContentItemQueryBuilder();
builder.ForContentType(config => config
- .When(maxLinkedItems > 0, linkOptions => linkOptions.WithLinkedItems(maxLinkedItems))
+ .WithLinkedItemsAndWebPageData(maxLinkedItems)
.Where(where =>
where.WhereEquals(nameof(IContentItemFieldsSource.SystemFields.ContentItemID), id))
.TopN(1))
- .When(!string.IsNullOrEmpty(languageName), lang => lang.InLanguage(languageName));
+ .WithLanguage(languageName);
var result = await ExecuteContentQuery(builder, dependencyFunc,
cancellationToken, CachePrefix, nameof(GetByIdAsync), id, maxLinkedItems);
@@ -169,11 +170,11 @@ public async Task> GetAllBySchema(string? language
var builder = new ContentItemQueryBuilder();
builder.ForContentType(config => config
- .When(maxLinkedItems > 0, linkOptions => linkOptions.WithLinkedItems(maxLinkedItems))
+ .WithLinkedItemsAndWebPageData(maxLinkedItems)
.Where(where => where
.WhereEquals(nameof(IContentQueryDataContainer.ContentItemGUID), id))
.TopN(1))
- .When(!string.IsNullOrEmpty(languageName), lang => lang.InLanguage(languageName));
+ .WithLanguage(languageName);
var result = await ExecuteContentQuery(builder, dependencyFunc,
cancellationToken, CachePrefix, nameof(GetByIdentifierAsync), id, maxLinkedItems);
@@ -189,11 +190,11 @@ public async Task> GetAllBySchema(string? language
builder.ForContentType(query =>
query
- .When(maxLinkedItems > 0, linkOptions => linkOptions.WithLinkedItems(maxLinkedItems))
+ .WithLinkedItemsAndWebPageData(maxLinkedItems)
.Where(where =>
where.WhereEquals(nameof(IContentItemFieldsSource.SystemFields.ContentItemName), name))
.TopN(1))
- .When(!string.IsNullOrEmpty(languageName), lang => lang.InLanguage(languageName));
+ .WithLanguage(languageName);
var result = await ExecuteContentQuery(builder, dependencyFunc,
cancellationToken, CachePrefix, nameof(GetByNameAsync), name, maxLinkedItems);
@@ -210,7 +211,7 @@ public async Task> GetBySmartFolderGuidAsync(Guid smartFold
var builder = new ContentItemQueryBuilder();
builder.ForContentTypes(config => config
- .When(maxLinkedItems > 0, linkOptions => linkOptions.WithLinkedItems(maxLinkedItems))
+ .WithLinkedItemsAndWebPageData(maxLinkedItems)
.OfContentType(contentType)
.InSmartFolder(smartFolderId));
@@ -229,7 +230,7 @@ public async Task> GetBySmartFolderIdAsync(int smartFolderI
var builder = new ContentItemQueryBuilder();
builder.ForContentTypes(config => config
- .When(maxLinkedItems > 0, linkOptions => linkOptions.WithLinkedItems(maxLinkedItems))
+ .WithLinkedItemsAndWebPageData(maxLinkedItems)
.OfContentType(contentType)
.InSmartFolder(smartFolderId));
@@ -255,7 +256,7 @@ public async Task> GetBySmartFolderIdAsync
var builder = new ContentItemQueryBuilder();
builder.ForContentTypes(config => config
- .When(maxLinkedItems > 0, linkOptions => linkOptions.WithLinkedItems(maxLinkedItems))
+ .WithLinkedItemsAndWebPageData(maxLinkedItems)
.OfContentType(contentTypes)
.InSmartFolder(smartFolderId));
@@ -284,7 +285,7 @@ public async Task> GetBySmartFolderIdAsync
var builder = new ContentItemQueryBuilder();
builder.ForContentTypes(config => config
- .When(maxLinkedItems > 0, linkOptions => linkOptions.WithLinkedItems(maxLinkedItems))
+ .WithLinkedItemsAndWebPageData(maxLinkedItems)
.OfContentType(contentTypes)
.InSmartFolder(smartFolderId));
@@ -314,7 +315,7 @@ public async Task> GetBySmartFolderIdAsync
var builder = new ContentItemQueryBuilder();
builder.ForContentTypes(config => config
- .When(maxLinkedItems > 0, linkOptions => linkOptions.WithLinkedItems(maxLinkedItems))
+ .WithLinkedItemsAndWebPageData(maxLinkedItems)
.OfContentType(contentTypes)
.InSmartFolder(smartFolderId));
@@ -344,7 +345,7 @@ public async Task> GetBySmartFolderIdAsync
var builder = new ContentItemQueryBuilder();
builder.ForContentTypes(config => config
- .When(maxLinkedItems > 0, linkOptions => linkOptions.WithLinkedItems(maxLinkedItems))
+ .WithLinkedItemsAndWebPageData(maxLinkedItems)
.OfContentType(contentTypes)
.InSmartFolder(smartFolderId));
@@ -374,8 +375,7 @@ public async Task> GetByTagsAsync(string columnName, IEnume
builder.ForContentType(config =>
config
- .When(maxLinkedItems > 0, options => options.WithLinkedItems(maxLinkedItems,
- linkOptions => linkOptions.IncludeWebPageData()))
+ .WithLinkedItemsAndWebPageData(maxLinkedItems)
.Where(where => where.WhereContainsTags(columnName, tagIdents)));
var result = await ExecuteContentQuery(builder, dependencyFunc,
diff --git a/src/XperienceCommunity.DataRepository/Extensions/ContentItemQueryBuilderExtensions.cs b/src/XperienceCommunity.DataRepository/Extensions/ContentItemQueryBuilderExtensions.cs
index fc0ed6f..a7b2f8b 100644
--- a/src/XperienceCommunity.DataRepository/Extensions/ContentItemQueryBuilderExtensions.cs
+++ b/src/XperienceCommunity.DataRepository/Extensions/ContentItemQueryBuilderExtensions.cs
@@ -39,4 +39,17 @@ public static ContentItemQueryBuilder When(this ContentItemQueryBuilder source,
return source;
}
+
+ ///
+ /// Configures the to filter by the specified language.
+ ///
+ /// The to apply the action to.
+ /// The language name.
+ /// The original with the action applied.
+ public static ContentItemQueryBuilder WithLanguage(this ContentItemQueryBuilder source, string? language)
+ {
+ source.When(!string.IsNullOrEmpty(language), q => q.InLanguage(language));
+
+ return source;
+ }
}
diff --git a/src/XperienceCommunity.DataRepository/Extensions/ContentTypeParametersExtensions.cs b/src/XperienceCommunity.DataRepository/Extensions/ContentTypeParametersExtensions.cs
index 6bfeeaf..39909a8 100644
--- a/src/XperienceCommunity.DataRepository/Extensions/ContentTypeParametersExtensions.cs
+++ b/src/XperienceCommunity.DataRepository/Extensions/ContentTypeParametersExtensions.cs
@@ -1,9 +1,25 @@
using CMS.ContentEngine;
+using CMS.DataEngine;
+using CMS.Websites;
namespace XperienceCommunity.DataRepository.Extensions;
public static class ContentTypeParametersExtensions
{
+
+ ///
+ /// Orders the instance by the WebPageItemOrder field in ascending order.
+ ///
+ /// The instance.
+ /// The instance ordered by WebPageItemOrder.
+ public static ContentTypeQueryParameters OrderByWebPageItemOrder(this ContentTypeQueryParameters source)
+ {
+ source
+ .OrderBy(OrderByColumn.Asc(nameof(IWebPageFieldsSource.SystemFields.WebPageItemOrder)));
+
+ return source;
+ }
+
///
/// Conditionally applies an action to the instance.
///
@@ -39,4 +55,32 @@ public static ContentTypesQueryParameters When(this ContentTypesQueryParameters
return source;
}
+
+ ///
+ /// Configures the instance to include linked items and web page data.
+ ///
+ /// The instance.
+ /// The maximum number of linked items to include.
+ /// The instance.
+ public static ContentTypesQueryParameters WithLinkedItemsAndWebPageData(this ContentTypesQueryParameters source, int maxLinkedItems)
+ {
+ source.When(maxLinkedItems > 0, options => options.WithLinkedItems(maxLinkedItems,
+ linkOptions => linkOptions.IncludeWebPageData()));
+
+ return source;
+ }
+
+ ///
+ /// Configures the instance to include linked items and web page data.
+ ///
+ /// The instance.
+ /// The maximum number of linked items to include.
+ /// The instance.
+ public static ContentTypeQueryParameters WithLinkedItemsAndWebPageData(this ContentTypeQueryParameters source, int maxLinkedItems)
+ {
+ source.When(maxLinkedItems > 0, options => options.WithLinkedItems(maxLinkedItems,
+ linkOptions => linkOptions.IncludeWebPageData()));
+
+ return source;
+ }
}
diff --git a/src/XperienceCommunity.DataRepository/Extensions/IContentItemFieldsSourceExtensions.cs b/src/XperienceCommunity.DataRepository/Extensions/IContentItemFieldsSourceExtensions.cs
index 9d62313..988931d 100644
--- a/src/XperienceCommunity.DataRepository/Extensions/IContentItemFieldsSourceExtensions.cs
+++ b/src/XperienceCommunity.DataRepository/Extensions/IContentItemFieldsSourceExtensions.cs
@@ -45,6 +45,13 @@ public static class IContentItemFieldsSourceExtensions
/// An enumerable containing the content item IDs.
public static IEnumerable GetContentItemIds(this IEnumerable? source) => source?.Select(x => x.SystemFields.ContentItemID) ?? [];
+ ///
+ /// Gets the content item GUIDs from the specified collection of content item fields sources.
+ ///
+ /// The collection of content item fields sources.
+ /// An enumerable containing the content item GUIDs.
+ public static IEnumerable GetContentItemGUIDs(this IEnumerable? source) => source?.Select(x => x.SystemFields.ContentItemGUID) ?? [];
+
///
/// Gets the content types from the specified collection of content item fields sources.
///
diff --git a/src/XperienceCommunity.DataRepository/Extensions/IWebPageFieldsSourceExtensions.cs b/src/XperienceCommunity.DataRepository/Extensions/IWebPageFieldsSourceExtensions.cs
index e82c2d4..444821c 100644
--- a/src/XperienceCommunity.DataRepository/Extensions/IWebPageFieldsSourceExtensions.cs
+++ b/src/XperienceCommunity.DataRepository/Extensions/IWebPageFieldsSourceExtensions.cs
@@ -44,4 +44,10 @@ public static class IWebPageFieldsSourceExtensions
/// An enumerable containing the web page item IDs.
public static IEnumerable GetWebPageItemIds(this IEnumerable? source) => source?.Select(x => x.SystemFields.WebPageItemID) ?? [];
+ ///
+ /// Gets the web page item GUIDs for the specified collection of .
+ ///
+ /// The collection of sources to get the web page item GUIDs for.
+ /// An enumerable containing the web page item GUIDs.
+ public static IEnumerable GetWebPageItemGuids(this IEnumerable? source) => source?.Select(x => x.SystemFields.WebPageItemGUID) ?? [];
}
diff --git a/src/XperienceCommunity.DataRepository/Extensions/TypeExtensions.cs b/src/XperienceCommunity.DataRepository/Extensions/TypeExtensions.cs
index 3f5a30b..49a5c2b 100644
--- a/src/XperienceCommunity.DataRepository/Extensions/TypeExtensions.cs
+++ b/src/XperienceCommunity.DataRepository/Extensions/TypeExtensions.cs
@@ -155,14 +155,17 @@ public static IEnumerable GetRelatedAssetItemGuids(this T source, Expre
{
if (property.GetValue(source) is AssetRelatedItem item)
{
- guids.Add(item.Identifier);
+ if (item.Identifier != Guid.Empty)
+ {
+ guids.Add(item.Identifier);
+ }
}
}
else if (typeof(IEnumerable).IsAssignableFrom(property.PropertyType))
{
if (property.GetValue(source) is IEnumerable items)
{
- guids.AddRange(items.Select(item => item.Identifier));
+ guids.AddRange(items.Where(item => item.Identifier != Guid.Empty).Select(item => item.Identifier));
}
}
}
@@ -189,14 +192,17 @@ public static IEnumerable GetRelatedAssetItemGuids(this T source) where
{
if (property.GetValue(source) is AssetRelatedItem item)
{
- guids.Add(item.Identifier);
+ if (item.Identifier != Guid.Empty)
+ {
+ guids.Add(item.Identifier);
+ }
}
}
else if (typeof(IEnumerable).IsAssignableFrom(property.PropertyType))
{
if (property.GetValue(source) is IEnumerable items)
{
- guids.AddRange(items.Select(item => item.Identifier));
+ guids.AddRange(items.Where(item => item.Identifier != Guid.Empty).Select(item => item.Identifier));
}
}
}
@@ -229,14 +235,17 @@ public static IEnumerable GetRelatedWebPageGuids(this T source, Express
{
if (property.GetValue(source) is WebPageRelatedItem item)
{
- guids.Add(item.WebPageGuid);
+ if (item.WebPageGuid != Guid.Empty)
+ {
+ guids.Add(item.WebPageGuid);
+ }
}
}
else if (typeof(IEnumerable).IsAssignableFrom(property.PropertyType))
{
if (property.GetValue(source) is IEnumerable items)
{
- guids.AddRange(items.Select(item => item.WebPageGuid));
+ guids.AddRange(items.Where(item => item.WebPageGuid != Guid.Empty).Select(item => item.WebPageGuid));
}
}
}
@@ -253,14 +262,17 @@ public static IEnumerable GetRelatedWebPageGuids(this T source, Express
{
if (property.GetValue(source) is WebPageRelatedItem item)
{
- guids.Add(item.WebPageGuid);
+ if (item.WebPageGuid != Guid.Empty)
+ {
+ guids.Add(item.WebPageGuid);
+ }
}
}
else if (typeof(IEnumerable).IsAssignableFrom(property.PropertyType))
{
if (property.GetValue(source) is IEnumerable items)
{
- guids.AddRange(items.Select(item => item.WebPageGuid));
+ guids.AddRange(items.Where(item => item.WebPageGuid != Guid.Empty).Select(item => item.WebPageGuid));
}
}
}
@@ -287,14 +299,17 @@ public static IEnumerable GetRelatedWebPageGuids(this T source) where T
{
if (property.GetValue(source) is WebPageRelatedItem item)
{
- guids.Add(item.WebPageGuid);
+ if (item.WebPageGuid != Guid.Empty)
+ {
+ guids.Add(item.WebPageGuid);
+ }
}
}
else if (typeof(IEnumerable).IsAssignableFrom(property.PropertyType))
{
if (property.GetValue(source) is IEnumerable items)
{
- guids.AddRange(items.Select(item => item.WebPageGuid));
+ guids.AddRange(items.Where(item => item.WebPageGuid != Guid.Empty).Select(item => item.WebPageGuid));
}
}
}
diff --git a/src/XperienceCommunity.DataRepository/PageTypeRepository.cs b/src/XperienceCommunity.DataRepository/PageTypeRepository.cs
index f1f59bb..c119502 100644
--- a/src/XperienceCommunity.DataRepository/PageTypeRepository.cs
+++ b/src/XperienceCommunity.DataRepository/PageTypeRepository.cs
@@ -1,5 +1,6 @@
-using CMS.ContentEngine;
-using CMS.DataEngine;
+using System.Collections.ObjectModel;
+
+using CMS.ContentEngine;
using CMS.Helpers;
using CMS.Websites;
using CMS.Websites.Routing;
@@ -10,10 +11,11 @@
using XperienceCommunity.DataRepository.Models;
#pragma warning disable S1121
+
namespace XperienceCommunity.DataRepository;
public sealed class PageTypeRepository(IProgressiveCache cache, IContentQueryExecutor executor,
- IWebsiteChannelContext websiteChannelContext, RepositoryOptions options, ICacheDependencyBuilder cacheDependencyBuilder) : BaseRepository(cache, executor,
+ IWebsiteChannelContext websiteChannelContext, RepositoryOptions options, ICacheDependencyBuilder cacheDependencyBuilder, IWebPageUrlRetriever webPageUrlRetriever) : BaseRepository(cache, executor,
websiteChannelContext, options, cacheDependencyBuilder), IPageRepository
where TEntity : class, IWebPageFieldsSource
{
@@ -31,15 +33,16 @@ public async Task> GetAllAsync(string? languageName, int ma
.ForContentType(
config =>
config
- .When(maxLinkedItems > 0, options => options.WithLinkedItems(maxLinkedItems,
- linkOptions => linkOptions.IncludeWebPageData()))
- .OrderBy(OrderByColumn.Asc(nameof(IWebPageFieldsSource.SystemFields.WebPageItemOrder)))
+ .WithLinkedItemsAndWebPageData(maxLinkedItems)
+ .OrderByWebPageItemOrder()
.ForWebsite(WebsiteChannelContext.WebsiteChannelName))
- .When(!string.IsNullOrEmpty(languageName), lang => lang.InLanguage(languageName));
+ .WithLanguage(languageName);
var result = await ExecutePageQuery(builder, dependencyFunc,
cancellationToken, CachePrefix, nameof(GetAllAsync), languageName ?? string.Empty, contentType, maxLinkedItems);
+ await UpdateWebPageUrls(webPageUrlRetriever, languageName, result, cancellationToken);
+
return result;
}
@@ -60,17 +63,18 @@ public async Task> GetAllAsync(IEnumerable nodeGuid,
.ForContentType(
config =>
config
- .When(maxLinkedItems > 0, options => options.WithLinkedItems(maxLinkedItems,
- linkOptions => linkOptions.IncludeWebPageData()))
- .OrderBy(OrderByColumn.Asc(nameof(IWebPageFieldsSource.SystemFields.WebPageItemOrder)))
+ .WithLinkedItemsAndWebPageData(maxLinkedItems)
+ .OrderByWebPageItemOrder()
.ForWebsite(WebsiteChannelContext.WebsiteChannelName)
.Where(where => where.WhereIn(nameof(IWebPageContentQueryDataContainer.WebPageItemGUID),
guidList)))
- .When(!string.IsNullOrEmpty(languageName), options => options.InLanguage(languageName));
+ .WithLanguage(languageName);
var result = await ExecutePageQuery(builder, dependencyFunc,
cancellationToken, CachePrefix, nameof(GetAllAsync), guidList, languageName ?? string.Empty, contentType, maxLinkedItems);
+ await UpdateWebPageUrls(webPageUrlRetriever, languageName, result, cancellationToken);
+
return result;
}
@@ -91,16 +95,17 @@ public async Task> GetAllAsync(IEnumerable itemIds, st
.ForContentType(
config =>
config
- .When(maxLinkedItems > 0, options => options.WithLinkedItems(maxLinkedItems,
- linkOptions => linkOptions.IncludeWebPageData()))
- .OrderBy(OrderByColumn.Asc(nameof(IWebPageFieldsSource.SystemFields.WebPageItemOrder)))
+ .WithLinkedItemsAndWebPageData(maxLinkedItems)
+ .OrderByWebPageItemOrder()
.Where(where =>
where.WhereIn(nameof(IWebPageFieldsSource.SystemFields.WebPageItemID), itemIdList)))
- .When(!string.IsNullOrEmpty(languageName), lang => lang.InLanguage(languageName));
+ .WithLanguage(languageName);
var result = await ExecutePageQuery(builder, dependencyFunc,
cancellationToken, CachePrefix, nameof(GetAllAsync), itemIdList, languageName ?? string.Empty, contentType, maxLinkedItems);
+ await UpdateWebPageUrls(webPageUrlRetriever, languageName, result, cancellationToken);
+
return result;
}
@@ -115,11 +120,11 @@ public async Task> GetAllBySchema(string? language
var builder = new ContentItemQueryBuilder();
builder.ForContentTypes(parameters => parameters
- .When(maxLinkedItems > 0, linkItemOptions => linkItemOptions.WithLinkedItems(maxLinkedItems))
+ .WithLinkedItemsAndWebPageData(maxLinkedItems)
.OfReusableSchema(schemaName)
.WithWebPageData()
.ForWebsite(WebsiteChannelContext.WebsiteChannelName))
- .When(!string.IsNullOrEmpty(languageName), lang => lang.InLanguage(languageName));
+ .WithLanguage(languageName);
var result = await ExecuteContentQuery(builder, dependencyFunc,
cancellationToken, CachePrefix, nameof(GetAllBySchema), schemaName, languageName ?? string.Empty, maxLinkedItems);
@@ -137,19 +142,20 @@ public async Task> GetAllBySchema(string? language
.ForContentType(contentType,
config =>
config
- .When(maxLinkedItems > 0, options => options.WithLinkedItems(maxLinkedItems,
- linkOptions => linkOptions.IncludeWebPageData()))
- .OrderBy(OrderByColumn.Asc(nameof(IWebPageFieldsSource.SystemFields.WebPageItemOrder)))
+ .WithLinkedItemsAndWebPageData(maxLinkedItems)
+ .OrderByWebPageItemOrder()
.ForWebsite(WebsiteChannelContext.WebsiteChannelName)
.Where(predicate =>
predicate.WhereEquals(nameof(IWebPageFieldsSource.SystemFields.WebPageItemGUID),
itemGuid))
.TopN(1))
- .When(!string.IsNullOrEmpty(languageName), lang => lang.InLanguage(languageName));
+ .WithLanguage(languageName);
var result = await ExecutePageQuery(builder, dependencyFunc,
cancellationToken, CachePrefix, nameof(GetByGuidAsync), itemGuid, contentType, maxLinkedItems);
+ await UpdateWebPageUrls(webPageUrlRetriever, languageName, result, cancellationToken);
+
return result.FirstOrDefault();
}
@@ -163,18 +169,19 @@ public async Task> GetAllBySchema(string? language
.ForContentType(contentType,
config =>
config
- .When(maxLinkedItems > 0, options => options.WithLinkedItems(maxLinkedItems,
- linkOptions => linkOptions.IncludeWebPageData()))
- .OrderBy(OrderByColumn.Asc(nameof(IWebPageFieldsSource.SystemFields.WebPageItemOrder)))
+ .WithLinkedItemsAndWebPageData(maxLinkedItems)
+ .OrderByWebPageItemOrder()
.ForWebsite(WebsiteChannelContext.WebsiteChannelName)
.Where(predicate =>
predicate.WhereEquals(nameof(IWebPageFieldsSource.SystemFields.WebPageItemID), id))
.TopN(1))
- .When(!string.IsNullOrEmpty(languageName), lang => lang.InLanguage(languageName));
+ .WithLanguage(languageName);
var result = await ExecutePageQuery(builder, dependencyFunc,
cancellationToken, CachePrefix, nameof(GetByIdAsync), id, contentType, maxLinkedItems);
+ await UpdateWebPageUrls(webPageUrlRetriever, languageName, result, cancellationToken);
+
return result.FirstOrDefault();
}
@@ -188,15 +195,17 @@ public async Task> GetByPathAsync(string path, string? lang
.ForContentType(contentType,
config =>
config
- .When(maxLinkedItems > 0, options => options.WithLinkedItems(maxLinkedItems,
- linkOptions => linkOptions.IncludeWebPageData()))
- .OrderBy(OrderByColumn.Asc(nameof(IWebPageFieldsSource.SystemFields.WebPageItemOrder)))
+ .WithLinkedItemsAndWebPageData(maxLinkedItems)
+ .OrderByWebPageItemOrder()
.ForWebsite(WebsiteChannelContext.WebsiteChannelName, PathMatch.Single(path)))
- .When(!string.IsNullOrEmpty(languageName), lang => lang.InLanguage(languageName));
+ .WithLanguage(languageName);
var result = await ExecutePageQuery(builder, dependencyFunc ?? (() => CacheDependencyHelper.CreateWebPageItemTypeCacheDependency([contentType], WebsiteChannelContext.WebsiteChannelName)),
cancellationToken, CachePrefix, nameof(GetByPathAsync), path, contentType, maxLinkedItems);
+
+ await UpdateWebPageUrls(webPageUrlRetriever, languageName, result, cancellationToken);
+
return result;
}
@@ -218,15 +227,16 @@ public async Task> GetByPathAsync(stri
.ForContentTypes(
config =>
config
- .When(maxLinkedItems > 0, options => options.WithLinkedItems(maxLinkedItems,
- linkOptions => linkOptions.IncludeWebPageData()))
+ .WithLinkedItemsAndWebPageData(maxLinkedItems)
.OfContentType(contentTypes)
.ForWebsite(WebsiteChannelContext.WebsiteChannelName, PathMatch.Single(path)))
- .When(!string.IsNullOrEmpty(languageName), lang => lang.InLanguage(languageName));
+ .WithLanguage(languageName);
var result = await ExecutePageQuery(builder, dependencyFunc,
cancellationToken, CachePrefix, nameof(GetByPathAsync), path, contentTypes, maxLinkedItems);
+ await UpdateWebPageUrls(webPageUrlRetriever, languageName, result, cancellationToken);
+
return result;
}
@@ -249,14 +259,15 @@ public async Task> GetByPathAsync(
config =>
config
.OfContentType(contentTypes)
- .When(maxLinkedItems > 0, options => options.WithLinkedItems(maxLinkedItems,
- linkOptions => linkOptions.IncludeWebPageData()))
+ .WithLinkedItemsAndWebPageData(maxLinkedItems)
.ForWebsite(WebsiteChannelContext.WebsiteChannelName, PathMatch.Single(path)))
- .When(!string.IsNullOrEmpty(languageName), lang => lang.InLanguage(languageName));
+ .WithLanguage(languageName);
var result = await ExecutePageQuery(builder, dependencyFunc,
cancellationToken, CachePrefix, nameof(GetByPathAsync), path, contentTypes, maxLinkedItems);
+ await UpdateWebPageUrls(webPageUrlRetriever, languageName, result, cancellationToken);
+
return result;
}
@@ -280,14 +291,15 @@ public async Task> GetByPathAsync
config
.OfContentType(contentTypes)
- .When(maxLinkedItems > 0, options => options.WithLinkedItems(maxLinkedItems,
- linkOptions => linkOptions.IncludeWebPageData()))
+ .WithLinkedItemsAndWebPageData(maxLinkedItems)
.ForWebsite(WebsiteChannelContext.WebsiteChannelName, PathMatch.Single(path)))
- .When(!string.IsNullOrEmpty(languageName), lang => lang.InLanguage(languageName));
+ .WithLanguage(languageName);
var result = await ExecutePageQuery(builder, dependencyFunc,
cancellationToken, CachePrefix, nameof(GetByPathAsync), path, contentTypes, maxLinkedItems);
+ await UpdateWebPageUrls(webPageUrlRetriever, languageName, result, cancellationToken);
+
return result;
}
@@ -306,12 +318,10 @@ public async Task> GetByTagsAsync(string columnName, IEnume
}
var builder = new ContentItemQueryBuilder()
- .ForContentType(contentType,
- config =>
+ .ForContentType(config =>
config
- .When(maxLinkedItems > 0, options => options.WithLinkedItems(maxLinkedItems,
- linkOptions => linkOptions.IncludeWebPageData()))
- .OrderBy(OrderByColumn.Asc(nameof(IWebPageFieldsSource.SystemFields.WebPageItemOrder)))
+ .WithLinkedItemsAndWebPageData(maxLinkedItems)
+ .OrderByWebPageItemOrder()
.ForWebsite(WebsiteChannelContext.WebsiteChannelName)
.Where(where => where.WhereContainsTags(columnName,
guidList)));
@@ -319,6 +329,21 @@ public async Task> GetByTagsAsync(string columnName, IEnume
var result = await ExecutePageQuery(builder, dependencyFunc,
cancellationToken, CachePrefix, nameof(GetByTagsAsync), columnName, guidList, maxLinkedItems);
+ await UpdateWebPageUrls(webPageUrlRetriever, null, result, cancellationToken);
+
return result;
}
+
+
+ private async Task UpdateWebPageUrls(IWebPageUrlRetriever webPageUrlRetriever, string? languageName, IEnumerable result, CancellationToken cancellationToken) where T : IWebPageFieldsSource
+ {
+ var webPageGuids = new ReadOnlyCollection(result.Select(x => x.SystemFields.WebPageItemGUID).ToArray());
+
+ var webpageLinks = await webPageUrlRetriever.Retrieve(webPageGuids, WebsiteChannelContext.WebsiteChannelName, languageName, WebsiteChannelContext.IsPreview, cancellationToken);
+
+ foreach (var item in result)
+ {
+ item.SystemFields.WebPageUrlPath = webpageLinks.FirstOrDefault(x => x.Key == item.SystemFields.WebPageItemGUID).Value.AbsoluteUrl;
+ }
+ }
}
diff --git a/src/XperienceCommunity.DataRepository/XperienceCommunity.DataRepository.csproj b/src/XperienceCommunity.DataRepository/XperienceCommunity.DataRepository.csproj
index 6640876..9d873a8 100644
--- a/src/XperienceCommunity.DataRepository/XperienceCommunity.DataRepository.csproj
+++ b/src/XperienceCommunity.DataRepository/XperienceCommunity.DataRepository.csproj
@@ -4,7 +4,7 @@
net8.0;net9.0
enable
enable
- $(NoWarn);NU1504;NU1505;NU1506;NU1701;1591;S1066
+ $(NoWarn);NU1504;NU1505;NU1506;NU1701;1591;S1066;S3267
@@ -18,7 +18,9 @@
-
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
diff --git a/src/XperienceCommunity.DataRepository/packages.lock.json b/src/XperienceCommunity.DataRepository/packages.lock.json
index ff568a3..a584007 100644
--- a/src/XperienceCommunity.DataRepository/packages.lock.json
+++ b/src/XperienceCommunity.DataRepository/packages.lock.json
@@ -25,9 +25,9 @@
},
"SonarAnalyzer.CSharp": {
"type": "Direct",
- "requested": "[10.4.0.108396, )",
- "resolved": "10.4.0.108396",
- "contentHash": "xGcLZ+dvkVuBbd3sjPur9X+1owSL/iDoxVFJLhMx3/vq1fmoKM2fwvrZ8ReAas6l715GJ/dWU2ckwlrRVopmbg=="
+ "requested": "[10.5.0.109200, )",
+ "resolved": "10.5.0.109200",
+ "contentHash": "yS8uepqf+HwSEZtkJR7O4siqfyGKX4Lu7mIB6TTppy59czq7qkFjZ+fB7NTRZg8a/Pu7tvwVhpEMcxUTiQZmSw=="
},
"AngleSharp": {
"type": "Transitive",
@@ -530,9 +530,9 @@
},
"SonarAnalyzer.CSharp": {
"type": "Direct",
- "requested": "[10.4.0.108396, )",
- "resolved": "10.4.0.108396",
- "contentHash": "xGcLZ+dvkVuBbd3sjPur9X+1owSL/iDoxVFJLhMx3/vq1fmoKM2fwvrZ8ReAas6l715GJ/dWU2ckwlrRVopmbg=="
+ "requested": "[10.5.0.109200, )",
+ "resolved": "10.5.0.109200",
+ "contentHash": "yS8uepqf+HwSEZtkJR7O4siqfyGKX4Lu7mIB6TTppy59czq7qkFjZ+fB7NTRZg8a/Pu7tvwVhpEMcxUTiQZmSw=="
},
"AngleSharp": {
"type": "Transitive",
diff --git a/tests/XperienceCommunity.DataRepository.Tests/Extensions/IContentItemFieldsSourceExtensionsTests.cs b/tests/XperienceCommunity.DataRepository.Tests/Extensions/IContentItemFieldsSourceExtensionsTests.cs
index 40a9504..a80e160 100644
--- a/tests/XperienceCommunity.DataRepository.Tests/Extensions/IContentItemFieldsSourceExtensionsTests.cs
+++ b/tests/XperienceCommunity.DataRepository.Tests/Extensions/IContentItemFieldsSourceExtensionsTests.cs
@@ -147,6 +147,25 @@ public void ToTypedList_ReturnsCorrectList()
Assert.That(result, Has.Count.EqualTo(2));
}
+ [Test]
+ public void GetContentItemGUIDs_ReturnsCorrectGUIDs()
+ {
+ var source = new List
+ {
+ Substitute.For(), Substitute.For()
+ };
+
+ var systemFields1 = new ContentItemFields { ContentItemGUID = Guid.NewGuid() };
+ var systemFields2 = new ContentItemFields { ContentItemGUID = Guid.NewGuid() };
+
+ source[0].SystemFields.Returns(systemFields1);
+ source[1].SystemFields.Returns(systemFields2);
+
+ var result = source.GetContentItemGUIDs();
+
+ Assert.That(result, Is.EqualTo(new[] { systemFields1.ContentItemGUID, systemFields2.ContentItemGUID }));
+ }
+
public class TestContentItemFieldsSource : IContentItemFieldsSource
{
public static string CONTENT_TYPE_NAME = "TestContentItemFieldsSource";
diff --git a/tests/XperienceCommunity.DataRepository.Tests/Extensions/IWebPageFieldsSourceExtensionsTests.cs b/tests/XperienceCommunity.DataRepository.Tests/Extensions/IWebPageFieldsSourceExtensionsTests.cs
index 54f52c2..b214789 100644
--- a/tests/XperienceCommunity.DataRepository.Tests/Extensions/IWebPageFieldsSourceExtensionsTests.cs
+++ b/tests/XperienceCommunity.DataRepository.Tests/Extensions/IWebPageFieldsSourceExtensionsTests.cs
@@ -135,4 +135,61 @@ public void GetContentTypes_ShouldReturnCorrectContentTypes_WhenSourcesAreNotNul
Assert.That(result, Is.EqualTo(new[] { "TestWebPageFieldsSource", "TestWebPageFieldsSource" }));
Assert.That(result, Is.EqualTo(new[] { "TestWebPageFieldsSource", "TestWebPageFieldsSource" }));
}
+ [Test]
+ public void GetCacheDependencyKey_ShouldReturnEmptyArray_WhenSourceIsNull()
+ {
+ IWebPageFieldsSource? source = null;
+
+ string[] result = source.GetCacheDependencyKey();
+
+ Assert.That(result, Is.Empty);
+ }
+
+ [Test]
+ public void GetCacheDependencyKeys_ShouldReturnEmptyArray_WhenSourcesAreNull()
+ {
+ IEnumerable? sources = null;
+
+ string[] result = sources.GetCacheDependencyKeys();
+
+ Assert.That(result, Is.Empty);
+ }
+
+ [Test]
+ public void GetWebPageItemIds_ShouldReturnEmptyArray_WhenSourcesAreNull()
+ {
+ IEnumerable? sources = null;
+
+ var result = sources.GetWebPageItemIds();
+
+ Assert.That(result, Is.Empty);
+ }
+
+ [Test]
+ public void GetWebPageItemGuids_ShouldReturnCorrectGuids_WhenSourcesAreNotNull()
+ {
+ var sources = new List
+ {
+ Substitute.For(), Substitute.For()
+ };
+
+ var systemFields1 = new WebPageFields() { WebPageItemGUID = Guid.NewGuid(), ContentItemIsSecured = false };
+ var systemFields2 = new WebPageFields() { WebPageItemGUID = Guid.NewGuid(), ContentItemIsSecured = false };
+
+ sources[0].SystemFields.Returns(systemFields1);
+ sources[1].SystemFields.Returns(systemFields2);
+
+ var result = sources.GetWebPageItemGuids();
+ Assert.That(result, Is.EqualTo(new[] { systemFields1.WebPageItemGUID, systemFields2.WebPageItemGUID }));
+ }
+
+ [Test]
+ public void GetWebPageItemGuids_ShouldReturnEmptyArray_WhenSourcesAreNull()
+ {
+ IEnumerable? sources = null;
+
+ var result = sources.GetWebPageItemGuids();
+
+ Assert.That(result, Is.Empty);
+ }
}
diff --git a/tests/XperienceCommunity.DataRepository.Tests/Extensions/TypeExtensionsTests.cs b/tests/XperienceCommunity.DataRepository.Tests/Extensions/TypeExtensionsTests.cs
index 433522e..ca68809 100644
--- a/tests/XperienceCommunity.DataRepository.Tests/Extensions/TypeExtensionsTests.cs
+++ b/tests/XperienceCommunity.DataRepository.Tests/Extensions/TypeExtensionsTests.cs
@@ -1,4 +1,5 @@
using CMS.ContentEngine;
+using CMS.MediaLibrary;
using CMS.Websites;
using NSubstitute;
@@ -158,7 +159,7 @@ public void GetRelatedWebPageGuids_SingleItem_ReturnsGuid()
var guid = Guid.NewGuid();
var relatedItem = new WebPageRelatedItem { WebPageGuid = guid };
- var source = new TestContentItemFieldsSource() { RelatedItem = relatedItem };
+ var source = new TestWebPageFieldsSource() { RelatedItem = relatedItem };
// Act
var result = source.GetRelatedWebPageGuids(x => x.RelatedItem);
@@ -190,6 +191,29 @@ public void GetRelatedWebPageGuids_MultipleItems_ReturnsGuids()
Assert.That(result, Is.EquivalentTo(new[] { guid1, guid2 }));
}
+ [Test]
+ public void GetRelatedWebPageGuids_NoPropertySpecified_MultipleItems_ReturnsGuids()
+ {
+ // Arrange
+ var guid1 = Guid.NewGuid();
+ var guid2 = Guid.NewGuid();
+
+ var relatedItems = new List
+ {
+ new() { WebPageGuid = guid1 },
+ new() { WebPageGuid = guid2 }
+ };
+
+ var source = new TestWebPageFieldsSource() { RelatedItems = relatedItems };
+
+
+ // Act
+ var result = source.GetRelatedWebPageGuids();
+
+ // Assert
+ Assert.That(result, Is.EquivalentTo(new[] { guid1, guid2 }));
+ }
+
[Test]
public void GetRelatedWebPageGuids_NoItems_ReturnsEmpty()
{
@@ -202,11 +226,88 @@ public void GetRelatedWebPageGuids_NoItems_ReturnsEmpty()
// Assert
Assert.That(result, Is.Empty);
}
+
+ [Test]
+ public void GetRelatedAssetItemGuids_SingleItem_ReturnsGuid()
+ {
+ // Arrange
+ var guid = Guid.NewGuid();
+ var relatedItem = new AssetRelatedItem { Identifier = guid };
+
+ var source = new TestContentItemFieldsSource() { RelatedAssetItem = relatedItem };
+
+ // Act
+ var result = source.GetRelatedAssetItemGuids(x => x.RelatedAssetItem);
+
+ // Assert
+ Assert.That(result, Is.EquivalentTo(new[] { guid }));
+ }
+
+ [Test]
+ public void GetRelatedAssetItemGuids_MultipleItems_ReturnsGuids()
+ {
+ // Arrange
+ var guid1 = Guid.NewGuid();
+ var guid2 = Guid.NewGuid();
+
+ var relatedItems = new List
+ {
+ new() { Identifier = guid1 },
+ new() { Identifier = guid2 }
+ };
+
+ var source = new TestContentItemFieldsSource() { RelatedAssetItems = relatedItems };
+
+ // Act
+ var result = source.GetRelatedAssetItemGuids(x => x.RelatedAssetItems);
+
+ // Assert
+ Assert.That(result, Is.EquivalentTo(new[] { guid1, guid2 }));
+ }
+
+ [Test]
+ public void GetRelatedAssetItemGuids_NoPropertyExpression_MultipleItems_ReturnsGuids()
+ {
+ // Arrange
+ var guid1 = Guid.NewGuid();
+ var guid2 = Guid.NewGuid();
+
+ var relatedItems = new List
+ {
+ new() { Identifier = guid1 },
+ new() { Identifier = guid2 }
+ };
+
+ var source = new TestContentItemFieldsSource() { RelatedAssetItems = relatedItems };
+
+ // Act
+ var result = source.GetRelatedAssetItemGuids();
+
+ // Assert
+ Assert.That(result, Is.EquivalentTo(new[] { guid1, guid2 }));
+ }
+
+ [Test]
+ public void GetRelatedAssetItemGuids_NoItems_ReturnsEmpty()
+ {
+ // Arrange
+ var source = new TestContentItemFieldsSource();
+
+ // Act
+ var result = source.GetRelatedAssetItemGuids(x => x.RelatedAssetItems);
+
+ // Assert
+ Assert.That(result, Is.Empty);
+ }
+
public class TestContentItemFieldsSource : IContentItemFieldsSource
{
public static string CONTENT_TYPE_NAME = "TestContentItemFieldsSource";
- public WebPageRelatedItem RelatedItem { get; set; } = new WebPageRelatedItem();
+ public AssetRelatedItem RelatedAssetItem { get; set; } = new AssetRelatedItem();
+
+
+ public IEnumerable RelatedAssetItems { get; set; } = [];
public ContentItemFields SystemFields => throw new NotImplementedException();
}
@@ -215,9 +316,13 @@ public class TestWebPageFieldsSource : IWebPageFieldsSource
{
public static string CONTENT_TYPE_NAME = "TestWebPageFieldsSource";
+ public WebPageRelatedItem RelatedItem { get; set; } = new WebPageRelatedItem();
+
public IEnumerable RelatedItems { get; set; } = [];
public WebPageFields SystemFields => throw new NotImplementedException();
}
+
+
}
}
diff --git a/tests/XperienceCommunity.DataRepository.Tests/XperienceCommunity.DataRepository.Tests.csproj b/tests/XperienceCommunity.DataRepository.Tests/XperienceCommunity.DataRepository.Tests.csproj
index 806e451..b985f4f 100644
--- a/tests/XperienceCommunity.DataRepository.Tests/XperienceCommunity.DataRepository.Tests.csproj
+++ b/tests/XperienceCommunity.DataRepository.Tests/XperienceCommunity.DataRepository.Tests.csproj
@@ -11,14 +11,20 @@
-
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
@@ -34,4 +40,11 @@
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
diff --git a/tests/XperienceCommunity.DataRepository.Tests/packages.lock.json b/tests/XperienceCommunity.DataRepository.Tests/packages.lock.json
index e097c5e..d641eee 100644
--- a/tests/XperienceCommunity.DataRepository.Tests/packages.lock.json
+++ b/tests/XperienceCommunity.DataRepository.Tests/packages.lock.json
@@ -4,9 +4,9 @@
"net8.0": {
"coverlet.collector": {
"type": "Direct",
- "requested": "[6.0.3, )",
- "resolved": "6.0.3",
- "contentHash": "SvLbRq7gjzE34BI90vP6ge812+PAjinNoKhdFZHwVEu/ozJgZY+0KyDh1K0teDeMeuzQJuF8OvleRBYXsZDz0A=="
+ "requested": "[6.0.4, )",
+ "resolved": "6.0.4",
+ "contentHash": "lkhqpF8Pu2Y7IiN7OntbsTtdbpR1syMsm2F3IgX6ootA4ffRqWL5jF7XipHuZQTdVuWG/gVAAcf8mjk8Tz0xPg=="
},
"Kentico.Xperience.Core": {
"type": "Direct",
@@ -62,9 +62,9 @@
},
"NUnit.Analyzers": {
"type": "Direct",
- "requested": "[4.5.0, )",
- "resolved": "4.5.0",
- "contentHash": "GQysJCO0mi4bAW64DolpTcYLU3euxLiv7o3EYkp2RPGalUm4vgzX6ANiRAyIDWSSWmYUtFqBlmOUH6WkzxEADw=="
+ "requested": "[4.6.0, )",
+ "resolved": "4.6.0",
+ "contentHash": "uK1TEViVBugOO6uDou1amu7CoNhrd2sEUFr/iaEmVfoeY8qq/zzWCCUZi97aCCSZmjnHKCCWKh3RucU27qPlKg=="
},
"NUnit3TestAdapter": {
"type": "Direct",
@@ -74,9 +74,9 @@
},
"SonarAnalyzer.CSharp": {
"type": "Direct",
- "requested": "[10.4.0.108396, )",
- "resolved": "10.4.0.108396",
- "contentHash": "xGcLZ+dvkVuBbd3sjPur9X+1owSL/iDoxVFJLhMx3/vq1fmoKM2fwvrZ8ReAas6l715GJ/dWU2ckwlrRVopmbg=="
+ "requested": "[10.5.0.109200, )",
+ "resolved": "10.5.0.109200",
+ "contentHash": "yS8uepqf+HwSEZtkJR7O4siqfyGKX4Lu7mIB6TTppy59czq7qkFjZ+fB7NTRZg8a/Pu7tvwVhpEMcxUTiQZmSw=="
},
"AngleSharp": {
"type": "Transitive",
@@ -596,9 +596,9 @@
"net9.0": {
"coverlet.collector": {
"type": "Direct",
- "requested": "[6.0.3, )",
- "resolved": "6.0.3",
- "contentHash": "SvLbRq7gjzE34BI90vP6ge812+PAjinNoKhdFZHwVEu/ozJgZY+0KyDh1K0teDeMeuzQJuF8OvleRBYXsZDz0A=="
+ "requested": "[6.0.4, )",
+ "resolved": "6.0.4",
+ "contentHash": "lkhqpF8Pu2Y7IiN7OntbsTtdbpR1syMsm2F3IgX6ootA4ffRqWL5jF7XipHuZQTdVuWG/gVAAcf8mjk8Tz0xPg=="
},
"Kentico.Xperience.Core": {
"type": "Direct",
@@ -654,9 +654,9 @@
},
"NUnit.Analyzers": {
"type": "Direct",
- "requested": "[4.5.0, )",
- "resolved": "4.5.0",
- "contentHash": "GQysJCO0mi4bAW64DolpTcYLU3euxLiv7o3EYkp2RPGalUm4vgzX6ANiRAyIDWSSWmYUtFqBlmOUH6WkzxEADw=="
+ "requested": "[4.6.0, )",
+ "resolved": "4.6.0",
+ "contentHash": "uK1TEViVBugOO6uDou1amu7CoNhrd2sEUFr/iaEmVfoeY8qq/zzWCCUZi97aCCSZmjnHKCCWKh3RucU27qPlKg=="
},
"NUnit3TestAdapter": {
"type": "Direct",
@@ -666,9 +666,9 @@
},
"SonarAnalyzer.CSharp": {
"type": "Direct",
- "requested": "[10.4.0.108396, )",
- "resolved": "10.4.0.108396",
- "contentHash": "xGcLZ+dvkVuBbd3sjPur9X+1owSL/iDoxVFJLhMx3/vq1fmoKM2fwvrZ8ReAas6l715GJ/dWU2ckwlrRVopmbg=="
+ "requested": "[10.5.0.109200, )",
+ "resolved": "10.5.0.109200",
+ "contentHash": "yS8uepqf+HwSEZtkJR7O4siqfyGKX4Lu7mIB6TTppy59czq7qkFjZ+fB7NTRZg8a/Pu7tvwVhpEMcxUTiQZmSw=="
},
"AngleSharp": {
"type": "Transitive",