diff --git a/backend/src/Squidex.Domain.Apps.Core.Model/Apps/Json/RolesSurrogate.cs b/backend/src/Squidex.Domain.Apps.Core.Model/Apps/Json/RolesSurrogate.cs index fe8241282..68cae9d2e 100644 --- a/backend/src/Squidex.Domain.Apps.Core.Model/Apps/Json/RolesSurrogate.cs +++ b/backend/src/Squidex.Domain.Apps.Core.Model/Apps/Json/RolesSurrogate.cs @@ -25,7 +25,7 @@ public sealed class RolesSurrogate : Dictionary, ISurrogate, ISurrogate()); @@ -105,7 +105,7 @@ public sealed class Roles return this; } - var newRole = new Role(name, null, new JsonObject()); + var newRole = new Role(name, null, JsonValue.Object()); if (!inner.TryAdd(name, newRole, out var updated)) { diff --git a/backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/AddDefaultValues.cs b/backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/AddDefaultValues.cs new file mode 100644 index 000000000..aa630f436 --- /dev/null +++ b/backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/AddDefaultValues.cs @@ -0,0 +1,103 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using NodaTime; +using Squidex.Domain.Apps.Core.Contents; +using Squidex.Domain.Apps.Core.Schemas; +using Squidex.Infrastructure.Json.Objects; + +namespace Squidex.Domain.Apps.Core.ConvertContent; + +public sealed class AddDefaultValues : IContentDataConverter, IContentItemConverter, IContentFieldConverter +{ + private readonly PartitionResolver partitionResolver; + private readonly IClock clock; + private Instant now; + + public bool IgnoreRequiredFields { get; init; } + + public bool IgnoreNonMasterFields { get; init; } + + public AddDefaultValues(PartitionResolver partitionResolver, IClock? clock = null) + { + this.partitionResolver = partitionResolver; + + this.clock = clock ?? SystemClock.Instance; + } + + public void ConvertDataBefore(Schema schema, ContentData data) + { + foreach (var field in schema.Fields) + { + if (data.TryGetValue(field.Name, out var fieldData) && fieldData != null) + { + continue; + } + + if ((field.RawProperties.IsRequired && IgnoreRequiredFields) || !DefaultValueChecker.HasDefaultValue(field)) + { + continue; + } + + data[field.Name] = new ContentFieldData(); + } + } + + public ContentFieldData? ConvertFieldAfter(IRootField field, ContentFieldData source) + { + var partitioning = partitionResolver(field.Partitioning); + + foreach (var partitionKey in partitioning.AllKeys) + { + if (!partitioning.IsMaster(partitionKey) && IgnoreNonMasterFields) + { + continue; + } + + Enrich(field, source, partitionKey); + } + + return source; + } + + public JsonObject ConvertItemBefore(IField parentField, JsonObject source, IEnumerable schema) + { + foreach (var field in schema) + { + Enrich(field, source, field.Name); + } + + return source; + } + + private void Enrich(IField field, Dictionary fieldData, string key) + { + if (fieldData.TryGetValue(key, out _) || (field.RawProperties.IsRequired && IgnoreRequiredFields)) + { + return; + } + + var defaultValue = DefaultValueFactory.CreateDefaultValue(field, GetNow(), key); + + if (defaultValue == default) + { + return; + } + + fieldData[key] = defaultValue; + } + + private Instant GetNow() + { + if (now == default) + { + now = clock.GetCurrentInstant(); + } + + return now; + } +} diff --git a/backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/AddSchemaNames.cs b/backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/AddSchemaNames.cs index ba0e0724b..d033c8d82 100644 --- a/backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/AddSchemaNames.cs +++ b/backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/AddSchemaNames.cs @@ -21,9 +21,9 @@ public sealed class AddSchemaNames : IContentItemConverter this.components = components; } - public JsonObject ConvertItem(IField field, JsonObject source) + public JsonObject ConvertItemBefore(IField parentField, JsonObject source, IEnumerable schema) { - if (field is IArrayField) + if (parentField is IArrayField) { return source; } @@ -40,9 +40,9 @@ public sealed class AddSchemaNames : IContentItemConverter var id = DomainId.Create(discriminator); - if (components.TryGetValue(id, out var schema)) + if (components.TryGetValue(id, out var component)) { - source["schemaName"] = schema.Name; + source["schemaName"] = component.Name; } return source; diff --git a/backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/ContentConverter.cs b/backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/ContentConverter.cs index 6555f0893..d7685db3f 100644 --- a/backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/ContentConverter.cs +++ b/backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/ContentConverter.cs @@ -16,8 +16,8 @@ namespace Squidex.Domain.Apps.Core.ConvertContent; public sealed class ContentConverter { + private readonly List dataConverters = new List(); private readonly List itemConverters = new List(); - private readonly List fieldAfterConverters = new List(); private readonly List fieldConverters = new List(); private readonly List valueConverters = new List(); private readonly ResolvedComponents components; @@ -31,6 +31,11 @@ public sealed class ContentConverter public ContentConverter Add(IConverter converter) { + if (converter is IContentDataConverter contentConverter) + { + dataConverters.Add(contentConverter); + } + if (converter is IContentItemConverter itemConverter) { itemConverters.Add(itemConverter); @@ -41,11 +46,6 @@ public sealed class ContentConverter fieldConverters.Add(fieldConverter); } - if (converter is IContentFieldAfterConverter fieldAfterConverter) - { - fieldAfterConverters.Add(fieldAfterConverter); - } - if (converter is IContentValueConverter valueConverter) { valueConverters.Add(valueConverter); @@ -56,12 +56,16 @@ public sealed class ContentConverter public ContentData Convert(ContentData content) { - Guard.NotNull(schema); - // The conversion process assumes that we have ownership of the data and can manipulate it. // Clones are only created to save allocations. var result = new ContentData(content.Count); + // Some conversions should be made early, e.g. calculating default values. + foreach (var converter in dataConverters) + { + converter.ConvertDataBefore(schema, content); + } + foreach (var (fieldName, fieldData) in content) { if (fieldData == null || !schema.FieldsByName.TryGetValue(fieldName, out var field)) @@ -88,34 +92,44 @@ public sealed class ContentConverter } } + // Some conversions should be done later. + foreach (var converter in dataConverters) + { + converter.ConvertDataAfter(schema, result); + } + return result; } - private ContentFieldData? ConvertField(IRootField field, ContentFieldData? data) + private ContentFieldData? ConvertField(IRootField field, ContentFieldData data) { foreach (var converter in fieldConverters) { - data = converter.ConvertField(field, data!); + var newData = converter.ConvertFieldBefore(field, data); - if (data == null) + if (newData == null) { - break; + return null; } + + data = newData; } return data; } - private ContentFieldData? ConvertFieldAfter(IRootField field, ContentFieldData? data) + private ContentFieldData? ConvertFieldAfter(IRootField field, ContentFieldData data) { - foreach (var converter in fieldAfterConverters) + foreach (var converter in fieldConverters) { - data = converter.ConvertFieldAfter(field, data!); + var newData = converter.ConvertFieldAfter(field, data); - if (data == null) + if (newData == null) { - break; + return null; } + + data = newData; } return data; @@ -206,7 +220,7 @@ public sealed class ContentConverter return (true, default); } - return (false, ConvertNested(component.FieldCollection, obj, parent)); + return (false, ConvertNested(component.FieldCollection, obj, parent, component.Fields)); } private (bool Remove, JsonValue) ConvertArrayItem(IArrayField field, JsonValue value) @@ -216,7 +230,7 @@ public sealed class ContentConverter return (true, default); } - return (false, ConvertNested(field.FieldCollection, obj, field)); + return (false, ConvertNested(field.FieldCollection, obj, field, field.Fields)); } private ContentFieldData ConvertValues(IField field, ContentFieldData source) @@ -244,8 +258,13 @@ public sealed class ContentConverter return result ?? source; } - private JsonValue ConvertNested(FieldCollection fields, JsonObject source, IField parent) where T : IField + private JsonValue ConvertNested(FieldCollection fields, JsonObject source, IField parent, IEnumerable fieldSchema) where T : IField { + foreach (var converter in itemConverters) + { + source = converter.ConvertItemBefore(parent, source, fieldSchema); + } + JsonObject? result = null; foreach (var (key, oldValue) in source) @@ -281,7 +300,7 @@ public sealed class ContentConverter foreach (var converter in itemConverters) { - result = converter.ConvertItem(parent, result); + result = converter.ConvertItemAfter(parent, result, fieldSchema); } return result ?? source; diff --git a/backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/DefaultValueChecker.cs b/backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/DefaultValueChecker.cs new file mode 100644 index 000000000..60de777df --- /dev/null +++ b/backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/DefaultValueChecker.cs @@ -0,0 +1,92 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using Squidex.Domain.Apps.Core.Schemas; +using Squidex.Infrastructure; + +namespace Squidex.Domain.Apps.Core.ConvertContent; + +internal sealed class DefaultValueChecker : IFieldPropertiesVisitor +{ + private static readonly DefaultValueChecker Instance = new DefaultValueChecker(); + + private DefaultValueChecker() + { + } + + public static bool HasDefaultValue(IField field) + { + Guard.NotNull(field); + + return field.RawProperties.Accept(Instance, None.Value); + } + + public bool Visit(ArrayFieldProperties properties, None args) + { + return true; + } + + public bool Visit(AssetsFieldProperties properties, None args) + { + return properties.DefaultValue != null || properties.DefaultValues != null; + } + + public bool Visit(BooleanFieldProperties properties, None args) + { + return properties.DefaultValue != null || properties.DefaultValues != null; + } + + public bool Visit(ComponentFieldProperties properties, None args) + { + return false; + } + + public bool Visit(ComponentsFieldProperties properties, None args) + { + return true; + } + + public bool Visit(DateTimeFieldProperties properties, None args) + { + return properties.DefaultValue != null || properties.DefaultValues != null || properties.CalculatedDefaultValue != null; + } + + public bool Visit(GeolocationFieldProperties properties, None args) + { + return false; + } + + public bool Visit(JsonFieldProperties properties, None args) + { + return false; + } + + public bool Visit(NumberFieldProperties properties, None args) + { + return properties.DefaultValue != null || properties.DefaultValues != null; + } + + public bool Visit(ReferencesFieldProperties properties, None args) + { + return properties.DefaultValue != null || properties.DefaultValues != null; + } + + public bool Visit(StringFieldProperties properties, None args) + { + return properties.DefaultValue != null || properties.DefaultValues != null; + } + + public bool Visit(TagsFieldProperties properties, None args) + { + return properties.DefaultValue != null || properties.DefaultValues != null; + } + + public bool Visit(UIFieldProperties properties, None args) + { + return false; + } +} diff --git a/backend/src/Squidex.Domain.Apps.Core.Operations/DefaultValues/DefaultValueFactory.cs b/backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/DefaultValueFactory.cs similarity index 96% rename from backend/src/Squidex.Domain.Apps.Core.Operations/DefaultValues/DefaultValueFactory.cs rename to backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/DefaultValueFactory.cs index 668bacc50..f8626c651 100644 --- a/backend/src/Squidex.Domain.Apps.Core.Operations/DefaultValues/DefaultValueFactory.cs +++ b/backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/DefaultValueFactory.cs @@ -13,7 +13,7 @@ using Squidex.Infrastructure.Json.Objects; #pragma warning disable SA1313 // Parameter names should begin with lower-case letter -namespace Squidex.Domain.Apps.Core.DefaultValues; +namespace Squidex.Domain.Apps.Core.ConvertContent; public sealed class DefaultValueFactory : IFieldPropertiesVisitor { @@ -30,9 +30,7 @@ public sealed class DefaultValueFactory : IFieldPropertiesVisitor schema) + { + return source; + } + + JsonObject ConvertItemAfter(IField parentField, JsonObject source, IEnumerable schema) + { + return source; + } } public interface IContentValueConverter : IConverter diff --git a/backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/ResolveInvariant.cs b/backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/ResolveFromPreviousPartitioning.cs similarity index 62% rename from backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/ResolveInvariant.cs rename to backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/ResolveFromPreviousPartitioning.cs index bdbb6168c..2592dff30 100644 --- a/backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/ResolveInvariant.cs +++ b/backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/ResolveFromPreviousPartitioning.cs @@ -11,22 +11,47 @@ using Squidex.Domain.Apps.Core.Schemas; namespace Squidex.Domain.Apps.Core.ConvertContent; -public sealed class ResolveInvariant : IContentFieldAfterConverter +public sealed class ResolveFromPreviousPartitioning : IContentFieldConverter { private readonly LanguagesConfig languages; - public ResolveInvariant(LanguagesConfig languages) + public ResolveFromPreviousPartitioning(LanguagesConfig languages) { this.languages = languages; } public ContentFieldData? ConvertFieldAfter(IRootField field, ContentFieldData source) { - if (!field.Partitioning.Equals(Partitioning.Invariant)) + if (field.Partitioning.Equals(Partitioning.Invariant)) + { + return ResolveInvariant(source); + } + else + { + return ResolveLocalized(source); + } + } + + private ContentFieldData ResolveLocalized(ContentFieldData source) + { + if (source.TryGetNonNull(languages.Master, out _)) { return source; } + if (source.TryGetNonNull(InvariantPartitioning.Key, out var value)) + { + source = new ContentFieldData + { + [languages.Master] = value + }; + } + + return source; + } + + private ContentFieldData ResolveInvariant(ContentFieldData source) + { if (source.TryGetNonNull(InvariantPartitioning.Key, out _)) { return source; diff --git a/backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/ResolveLanguages.cs b/backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/ResolveLanguages.cs index d30ca0b5d..349f27b96 100644 --- a/backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/ResolveLanguages.cs +++ b/backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/ResolveLanguages.cs @@ -12,13 +12,14 @@ using Squidex.Infrastructure; namespace Squidex.Domain.Apps.Core.ConvertContent; -public sealed class ResolveLanguages : IContentFieldAfterConverter +public sealed class ResolveLanguages : IContentFieldConverter { private readonly LanguagesConfig languages; - private readonly bool resolveFallback; private readonly HashSet languageCodes; - public ResolveLanguages(LanguagesConfig languages, bool resolveFallback = true, params Language[] filteredLanguages) + public bool ResolveFallback { get; init; } + + public ResolveLanguages(LanguagesConfig languages, params Language[] filteredLanguages) { this.languages = languages; @@ -35,8 +36,6 @@ public sealed class ResolveLanguages : IContentFieldAfterConverter { languageCodes.Add(languages.Master); } - - this.resolveFallback = resolveFallback; } public ContentFieldData? ConvertFieldAfter(IRootField field, ContentFieldData source) @@ -46,15 +45,7 @@ public sealed class ResolveLanguages : IContentFieldAfterConverter return source; } - if (source.TryGetNonNull(InvariantPartitioning.Key, out var value)) - { - source = new ContentFieldData - { - [languages.Master] = value - }; - } - - if (resolveFallback) + if (ResolveFallback) { foreach (var languageCode in languageCodes) { @@ -65,6 +56,11 @@ public sealed class ResolveLanguages : IContentFieldAfterConverter foreach (var fallback in languages.GetPriorities(languageCode)) { + if (fallback == languageCode) + { + continue; + } + if (source.TryGetNonNull(fallback, out var fallbackValue)) { source[languageCode] = fallbackValue; diff --git a/backend/src/Squidex.Domain.Apps.Core.Operations/DefaultValues/DefaultValueExtensions.cs b/backend/src/Squidex.Domain.Apps.Core.Operations/DefaultValues/DefaultValueExtensions.cs deleted file mode 100644 index 741f75841..000000000 --- a/backend/src/Squidex.Domain.Apps.Core.Operations/DefaultValues/DefaultValueExtensions.cs +++ /dev/null @@ -1,57 +0,0 @@ -// ========================================================================== -// Squidex Headless CMS -// ========================================================================== -// Copyright (c) Squidex UG (haftungsbeschraenkt) -// All rights reserved. Licensed under the MIT license. -// ========================================================================== - -using NodaTime; -using Squidex.Domain.Apps.Core.Contents; -using Squidex.Domain.Apps.Core.Schemas; -using Squidex.Infrastructure; - -namespace Squidex.Domain.Apps.Core.DefaultValues; - -public static class DefaultValueExtensions -{ - public static void GenerateDefaultValues(this ContentData data, Schema schema, PartitionResolver partitionResolver) - { - Guard.NotNull(schema); - Guard.NotNull(partitionResolver); - - foreach (var field in schema.Fields) - { - var fieldData = data.GetOrCreate(field.Name, _ => new ContentFieldData()); - - if (fieldData != null) - { - var partitioning = partitionResolver(field.Partitioning); - - foreach (var partitionKey in partitioning.AllKeys) - { - Enrich(field, fieldData, partitionKey); - } - - if (fieldData.Count > 0) - { - data[field.Name] = fieldData; - } - } - } - } - - private static void Enrich(IField field, ContentFieldData fieldData, string partitionKey) - { - var defaultValue = DefaultValueFactory.CreateDefaultValue(field, SystemClock.Instance.GetCurrentInstant(), partitionKey); - - if (field.RawProperties.IsRequired || defaultValue == default) - { - return; - } - - if (!fieldData.TryGetValue(partitionKey, out _)) - { - fieldData.AddLocalized(partitionKey, defaultValue); - } - } -} diff --git a/backend/src/Squidex.Domain.Apps.Core.Operations/ExtractReferenceIds/ContentReferencesExtensions.cs b/backend/src/Squidex.Domain.Apps.Core.Operations/ExtractReferenceIds/ContentReferencesExtensions.cs index 41e1ecfbb..2cee87697 100644 --- a/backend/src/Squidex.Domain.Apps.Core.Operations/ExtractReferenceIds/ContentReferencesExtensions.cs +++ b/backend/src/Squidex.Domain.Apps.Core.Operations/ExtractReferenceIds/ContentReferencesExtensions.cs @@ -105,7 +105,7 @@ public static class ContentReferencesExtensions Guard.NotNull(schema); Guard.NotNull(partitioning); - var result = new JsonObject(); + var result = JsonValue.Object(); foreach (var partitionKey in partitioning.AllKeys) { diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoAssetFolderRepository.cs b/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoAssetFolderRepository.cs index 3179ecd14..3405acabe 100644 --- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoAssetFolderRepository.cs +++ b/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoAssetFolderRepository.cs @@ -38,7 +38,7 @@ public sealed partial class MongoAssetFolderRepository : MongoRepositoryBase> QueryAsync(DomainId appId, DomainId parentId, + public async Task> QueryAsync(DomainId appId, DomainId? parentId, CancellationToken ct = default) { using (Telemetry.Activities.StartActivity("MongoAssetFolderRepository/QueryAsync")) @@ -53,7 +53,7 @@ public sealed partial class MongoAssetFolderRepository : MongoRepositoryBase> QueryChildIdsAsync(DomainId appId, DomainId parentId, + public async Task> QueryChildIdsAsync(DomainId appId, DomainId? parentId, CancellationToken ct = default) { using (Telemetry.Activities.StartActivity("MongoAssetFolderRepository/QueryChildIdsAsync")) diff --git a/backend/src/Squidex.Domain.Apps.Entities/Apps/AppUISettings.cs b/backend/src/Squidex.Domain.Apps.Entities/Apps/AppUISettings.cs index 0deea73e1..bbc59596a 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Apps/AppUISettings.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Apps/AppUISettings.cs @@ -18,7 +18,7 @@ public sealed class AppUISettings : IAppUISettings, IDeleter [CollectionName("UISettings")] public sealed class State { - public JsonObject Settings { get; set; } = new JsonObject(); + public JsonObject Settings { get; set; } = JsonValue.Object(); public bool Set(JsonObject settings) { @@ -82,7 +82,7 @@ public sealed class AppUISettings : IAppUISettings, IDeleter { if (add) { - found = new JsonObject(); + found = JsonValue.Object(); current[segment] = found; } diff --git a/backend/src/Squidex.Domain.Apps.Entities/Assets/IAssetQueryService.cs b/backend/src/Squidex.Domain.Apps.Entities/Assets/IAssetQueryService.cs index b0337b00b..6bcde49ce 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Assets/IAssetQueryService.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Assets/IAssetQueryService.cs @@ -14,10 +14,7 @@ public interface IAssetQueryService Task> QueryAsync(Context context, DomainId? parentId, Q q, CancellationToken ct = default); - Task> QueryAssetFoldersAsync(Context context, DomainId parentId, - CancellationToken ct = default); - - Task> QueryAssetFoldersAsync(DomainId appId, DomainId parentId, + Task> QueryAssetFoldersAsync(Context context, DomainId? parentId, CancellationToken ct = default); Task> FindAssetFolderAsync(DomainId appId, DomainId id, diff --git a/backend/src/Squidex.Domain.Apps.Entities/Assets/Queries/AssetQueryService.cs b/backend/src/Squidex.Domain.Apps.Entities/Assets/Queries/AssetQueryService.cs index 3e561f824..ad32ff49e 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Assets/Queries/AssetQueryService.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Assets/Queries/AssetQueryService.cs @@ -64,20 +64,7 @@ public sealed class AssetQueryService : IAssetQueryService } } - public async Task> QueryAssetFoldersAsync(DomainId appId, DomainId parentId, - CancellationToken ct = default) - { - using (var activity = Telemetry.Activities.StartActivity("AssetQueryService/QueryAssetFoldersAsync")) - { - activity?.SetTag("folderId", parentId); - - var assetFolders = await QueryFoldersCoreAsync(appId, parentId, ct); - - return assetFolders; - } - } - - public async Task> QueryAssetFoldersAsync(Context context, DomainId parentId, + public async Task> QueryAssetFoldersAsync(Context context, DomainId? parentId, CancellationToken ct = default) { using (var activity = Telemetry.Activities.StartActivity("AssetQueryService/QueryAssetFoldersAsync")) @@ -243,7 +230,7 @@ public sealed class AssetQueryService : IAssetQueryService } } - private async Task> QueryFoldersCoreAsync(Context context, DomainId parentId, + private async Task> QueryFoldersCoreAsync(Context context, DomainId? parentId, CancellationToken ct) { using (var combined = CancellationTokenSource.CreateLinkedTokenSource(ct)) @@ -255,18 +242,6 @@ public sealed class AssetQueryService : IAssetQueryService } } - private async Task> QueryFoldersCoreAsync(DomainId appId, DomainId parentId, - CancellationToken ct) - { - using (var combined = CancellationTokenSource.CreateLinkedTokenSource(ct)) - { - // Enforce a hard timeout - combined.CancelAfter(options.TimeoutQuery); - - return await assetFolderRepository.QueryAsync(appId, parentId, combined.Token); - } - } - private async Task> QueryCoreAsync(Context context, DomainId? parentId, Q q, CancellationToken ct) { diff --git a/backend/src/Squidex.Domain.Apps.Entities/Assets/Repositories/IAssetFolderRepository.cs b/backend/src/Squidex.Domain.Apps.Entities/Assets/Repositories/IAssetFolderRepository.cs index d928b9704..3606e6515 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Assets/Repositories/IAssetFolderRepository.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Assets/Repositories/IAssetFolderRepository.cs @@ -11,10 +11,10 @@ namespace Squidex.Domain.Apps.Entities.Assets.Repositories; public interface IAssetFolderRepository { - Task> QueryAsync(DomainId appId, DomainId parentId, + Task> QueryAsync(DomainId appId, DomainId? parentId, CancellationToken ct = default); - Task> QueryChildIdsAsync(DomainId appId, DomainId parentId, + Task> QueryChildIdsAsync(DomainId appId, DomainId? parentId, CancellationToken ct = default); Task FindAssetFolderAsync(DomainId appId, DomainId id, diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/DomainObject/ContentDomainObject.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/DomainObject/ContentDomainObject.cs index fb1e7c479..be5df948e 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/DomainObject/ContentDomainObject.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/DomainObject/ContentDomainObject.cs @@ -246,7 +246,7 @@ public partial class ContentDomainObject : DomainObject value) { - var result = new JsonObject(); + var result = JsonValue.Object(); foreach (var field in Fields) { diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Primitives/JsonGraphType.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Primitives/JsonGraphType.cs index 0f2ac5e3e..d2d65061f 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Primitives/JsonGraphType.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Primitives/JsonGraphType.cs @@ -59,7 +59,7 @@ public sealed class JsonGraphType : JsonNoopGraphType case GraphQLObjectValue objectValue: { - var json = new JsonObject(); + var json = JsonValue.Object(); if (objectValue.Fields != null) { @@ -86,7 +86,7 @@ public sealed class JsonGraphType : JsonNoopGraphType case IDictionary obj: { - var json = new JsonObject(); + var json = JsonValue.Object(); foreach (var (key, value) in obj) { diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/Queries/Steps/ConvertData.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/Queries/Steps/ConvertData.cs index 2413fdd6d..d2df0ea64 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/Queries/Steps/ConvertData.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/Queries/Steps/ConvertData.cs @@ -126,13 +126,20 @@ public sealed class ConvertData : IContentEnricherStep converter.Add(cleanReferences); } - converter.Add(new ResolveInvariant(context.App.Languages)); + converter.Add(new ResolveFromPreviousPartitioning(context.App.Languages)); + + if (!context.IsFrontendClient) + { + converter.Add(new AddDefaultValues(context.App.PartitionResolver()) { IgnoreNonMasterFields = true }); + } converter.Add( - new ResolveLanguages(context.App.Languages, - context.IsFrontendClient == false && - context.ShouldResolveLanguages(), - context.Languages().ToArray())); + new ResolveLanguages( + context.App.Languages, + context.Languages().ToArray()) + { + ResolveFallback = !context.IsFrontendClient && context.ShouldResolveLanguages() + }); if (!context.IsFrontendClient) { diff --git a/backend/src/Squidex.Domain.Users.MongoDb/MongoUserStore.cs b/backend/src/Squidex.Domain.Users.MongoDb/MongoUserStore.cs index 7950e824d..2311bf2e1 100644 --- a/backend/src/Squidex.Domain.Users.MongoDb/MongoUserStore.cs +++ b/backend/src/Squidex.Domain.Users.MongoDb/MongoUserStore.cs @@ -210,7 +210,7 @@ public sealed class MongoUserStore : public async Task FindByLoginAsync(string loginProvider, string providerKey, CancellationToken cancellationToken) { - var result = await Collection.Find(x => x.Logins.Exists(y => y.LoginProvider == loginProvider && y.ProviderKey == providerKey)).FirstOrDefaultAsync(cancellationToken); + var result = await Collection.Find(Filter.ElemMatch(x => x.Logins, BuildFilter(loginProvider, providerKey))).FirstOrDefaultAsync(cancellationToken); return result; } @@ -650,4 +650,13 @@ public sealed class MongoUserStore : return Task.FromResult(false); } + + private static FilterDefinition BuildFilter(string loginProvider, string providerKey) + { + var filter = Builders.Filter; + + return filter.And( + filter.Eq(x => x.LoginProvider, loginProvider), + filter.Eq(x => x.ProviderKey, providerKey)); + } } diff --git a/backend/src/Squidex.Web/ErrorDto.cs b/backend/src/Squidex.Web/ErrorDto.cs index d065b0c69..ccb5943bb 100644 --- a/backend/src/Squidex.Web/ErrorDto.cs +++ b/backend/src/Squidex.Web/ErrorDto.cs @@ -14,7 +14,7 @@ public sealed class ErrorDto { [LocalizedRequired] [Display(Description = "Error message.")] - public string? Message { get; set; } + public string Message { get; set; } [Display(Description = "The error code.")] public string? ErrorCode { get; set; } diff --git a/backend/src/Squidex.Web/OpenApiRequestAttribute.cs b/backend/src/Squidex.Web/OpenApiRequestAttribute.cs new file mode 100644 index 000000000..451e87c1c --- /dev/null +++ b/backend/src/Squidex.Web/OpenApiRequestAttribute.cs @@ -0,0 +1,13 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +namespace Squidex.Web; + +[AttributeUsage(AttributeTargets.Class)] +public sealed class OpenApiRequestAttribute : Attribute +{ +} diff --git a/backend/src/Squidex/Areas/Api/Config/OpenApi/OpenApiServices.cs b/backend/src/Squidex/Areas/Api/Config/OpenApi/OpenApiServices.cs index 2799e77d0..936f3dfdf 100644 --- a/backend/src/Squidex/Areas/Api/Config/OpenApi/OpenApiServices.cs +++ b/backend/src/Squidex/Areas/Api/Config/OpenApi/OpenApiServices.cs @@ -86,6 +86,16 @@ public static class OpenApiServices private static void ConfigureSchemaSettings(JsonSchemaGeneratorSettings settings, TypeRegistry typeRegistry, bool flatten) { + settings.AllowReferencesWithProperties = true; + settings.DefaultDictionaryValueReferenceTypeNullHandling = ReferenceTypeNullHandling.NotNull; + settings.DefaultReferenceTypeNullHandling = ReferenceTypeNullHandling.NotNull; + settings.FlattenInheritanceHierarchy = flatten; + settings.ReflectionService = new ReflectionServices(); + settings.SchemaNameGenerator = new SchemaNameGenerator(); + settings.SchemaProcessors.Add(new DiscriminatorProcessor(typeRegistry)); + settings.SchemaProcessors.Add(new RequiredSchemaProcessor()); + settings.SchemaType = NJsonSchema.SchemaType.OpenApi3; + settings.TypeMappers = new List { CreateAnyMap>(), @@ -106,14 +116,6 @@ public static class OpenApiServices CreateStringMap(), CreateStringMap(), }; - - settings.AllowReferencesWithProperties = true; - settings.DefaultReferenceTypeNullHandling = ReferenceTypeNullHandling.NotNull; - settings.FlattenInheritanceHierarchy = flatten; - settings.SchemaNameGenerator = new SchemaNameGenerator(); - settings.SchemaProcessors.Add(new DiscriminatorProcessor(typeRegistry)); - settings.SchemaType = NJsonSchema.SchemaType.OpenApi3; - settings.ReflectionService = new ReflectionServices(); } private static ITypeMapper CreateObjectMap() diff --git a/backend/src/Squidex/Areas/Api/Config/OpenApi/RequiredSchemaProcessor.cs b/backend/src/Squidex/Areas/Api/Config/OpenApi/RequiredSchemaProcessor.cs new file mode 100644 index 000000000..496107269 --- /dev/null +++ b/backend/src/Squidex/Areas/Api/Config/OpenApi/RequiredSchemaProcessor.cs @@ -0,0 +1,46 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using NJsonSchema; +using NJsonSchema.Generation; +using Squidex.Web; + +namespace Squidex.Areas.Api.Config.OpenApi; + +public sealed class RequiredSchemaProcessor : ISchemaProcessor +{ + public void Process(SchemaProcessorContext context) + { + if (context.ContextualType.GetAttribute() != null) + { + return; + } + + FixRequired(context.Schema); + + foreach (var schema in context.Schema.AllOf) + { + FixRequired(schema); + } + + foreach (var schema in context.Schema.OneOf) + { + FixRequired(schema); + } + + static void FixRequired(JsonSchema schema) + { + foreach (var property in schema.Properties.Values) + { + if (!property.IsNullable(SchemaType.OpenApi3)) + { + property.IsRequired = true; + } + } + } + } +} diff --git a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/AddLanguageDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/AddLanguageDto.cs index 30039d6a0..4a6136b2b 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/AddLanguageDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/AddLanguageDto.cs @@ -9,9 +9,11 @@ using Squidex.Domain.Apps.Entities.Apps.Commands; using Squidex.Infrastructure; using Squidex.Infrastructure.Reflection; using Squidex.Infrastructure.Validation; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Apps.Models; +[OpenApiRequest] public sealed class AddLanguageDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/AddRoleDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/AddRoleDto.cs index edc96be92..d752761bb 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/AddRoleDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/AddRoleDto.cs @@ -7,9 +7,11 @@ using Squidex.Domain.Apps.Entities.Apps.Commands; using Squidex.Infrastructure.Validation; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Apps.Models; +[OpenApiRequest] public sealed class AddRoleDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/AddWorkflowDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/AddWorkflowDto.cs index c21449264..6c5cce74c 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/AddWorkflowDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/AddWorkflowDto.cs @@ -7,9 +7,11 @@ using Squidex.Domain.Apps.Entities.Apps.Commands; using Squidex.Infrastructure.Validation; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Apps.Models; +[OpenApiRequest] public sealed class AddWorkflowDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/AppDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/AppDto.cs index 1d3a89536..e5fdcabda 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/AppDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/AppDto.cs @@ -36,7 +36,6 @@ public sealed class AppDto : Resource /// /// The name of the app. /// - [LocalizedRequired] [LocalizedRegularExpression("^[a-z0-9]+(\\-[a-z0-9]+)*$")] public string Name { get; set; } @@ -94,7 +93,6 @@ public sealed class AppDto : Resource /// /// The properties from the role. /// - [LocalizedRequired] public JsonObject RoleProperties { get; set; } public static AppDto FromDomain(IAppEntity app, string userId, bool isFrontend, Resources resources) @@ -125,7 +123,7 @@ public sealed class AppDto : Resource } else { - result.RoleProperties = new JsonObject(); + result.RoleProperties = JsonValue.Object(); } foreach (var (key, value) in resources.Context.UserPrincipal.Claims.GetUIProperties(app.Name)) diff --git a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/AppLanguageDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/AppLanguageDto.cs index cd73b3286..1ccfa93e0 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/AppLanguageDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/AppLanguageDto.cs @@ -18,19 +18,16 @@ public sealed class AppLanguageDto : Resource /// /// The iso code of the language. /// - [LocalizedRequired] public string Iso2Code { get; set; } /// /// The english name of the language. /// - [LocalizedRequired] public string EnglishName { get; set; } /// /// The fallback languages. /// - [LocalizedRequired] public Language[] Fallback { get; set; } /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/AppLanguagesDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/AppLanguagesDto.cs index 94c78e1b5..d80323b60 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/AppLanguagesDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/AppLanguagesDto.cs @@ -16,7 +16,6 @@ public sealed class AppLanguagesDto : Resource /// /// The languages. /// - [LocalizedRequired] public AppLanguageDto[] Items { get; set; } public static AppLanguagesDto FromDomain(IAppEntity app, Resources resources) diff --git a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/AppSettingsDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/AppSettingsDto.cs index f9b34d804..c67f7e0ef 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/AppSettingsDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/AppSettingsDto.cs @@ -16,13 +16,11 @@ public sealed class AppSettingsDto : Resource /// /// The configured app patterns. /// - [LocalizedRequired] public PatternDto[] Patterns { get; set; } /// /// The configured UI editors. /// - [LocalizedRequired] public EditorDto[] Editors { get; set; } /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/ClientDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/ClientDto.cs index 667d91d06..29d0bfc1e 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/ClientDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/ClientDto.cs @@ -7,7 +7,6 @@ using Squidex.Domain.Apps.Core.Apps; using Squidex.Infrastructure.Reflection; -using Squidex.Infrastructure.Validation; using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Apps.Models; @@ -17,19 +16,16 @@ public sealed class ClientDto : Resource /// /// The client id. /// - [LocalizedRequired] public string Id { get; set; } /// /// The client secret. /// - [LocalizedRequired] public string Secret { get; set; } /// /// The client name. /// - [LocalizedRequired] public string Name { get; set; } /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/ClientsDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/ClientsDto.cs index 7fbfd2afb..8e1b30c8e 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/ClientsDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/ClientsDto.cs @@ -16,7 +16,6 @@ public sealed class ClientsDto : Resource /// /// The clients. /// - [LocalizedRequired] public ClientDto[] Items { get; set; } public static ClientsDto FromApp(IAppEntity app, Resources resources) diff --git a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/CreateAppDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/CreateAppDto.cs index 5fcbbe83c..48a7928b2 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/CreateAppDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/CreateAppDto.cs @@ -8,9 +8,11 @@ using Squidex.Domain.Apps.Entities.Apps.Commands; using Squidex.Infrastructure.Reflection; using Squidex.Infrastructure.Validation; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Apps.Models; +[OpenApiRequest] public sealed class CreateAppDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/CreateClientDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/CreateClientDto.cs index f61630761..e190f1793 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/CreateClientDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/CreateClientDto.cs @@ -8,9 +8,11 @@ using Squidex.Domain.Apps.Entities.Apps.Commands; using Squidex.Infrastructure.Reflection; using Squidex.Infrastructure.Validation; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Apps.Models; +[OpenApiRequest] public sealed class CreateClientDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/EditorDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/EditorDto.cs index 9814af8a4..b5bc45b0a 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/EditorDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/EditorDto.cs @@ -16,13 +16,11 @@ public sealed class EditorDto /// /// The name of the editor. /// - [LocalizedRequired] public string Name { get; set; } /// /// The url to the editor. /// - [LocalizedRequired] public string Url { get; set; } public static EditorDto FromDomain(Editor editor) diff --git a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/PatternDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/PatternDto.cs index 8ae33136f..e12d2d802 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/PatternDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/PatternDto.cs @@ -16,13 +16,11 @@ public sealed class PatternDto /// /// The name of the suggestion. /// - [LocalizedRequired] public string Name { get; set; } /// /// The regex pattern. /// - [LocalizedRequired] public string Regex { get; set; } /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/RoleDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/RoleDto.cs index ae7f4d9e0..ab3bb3d5c 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/RoleDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/RoleDto.cs @@ -8,7 +8,6 @@ using Squidex.Domain.Apps.Core.Apps; using Squidex.Domain.Apps.Entities.Apps; using Squidex.Infrastructure.Json.Objects; -using Squidex.Infrastructure.Validation; using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Apps.Models; @@ -18,7 +17,6 @@ public sealed class RoleDto : Resource /// /// The role name. /// - [LocalizedRequired] public string Name { get; set; } /// @@ -39,13 +37,11 @@ public sealed class RoleDto : Resource /// /// Associated list of permissions. /// - [LocalizedRequired] public string[] Permissions { get; set; } /// /// Associated list of UI properties. /// - [LocalizedRequired] public JsonObject Properties { get; set; } public static RoleDto FromDomain(Role role, IAppEntity app) diff --git a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/RolesDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/RolesDto.cs index da896bee0..c975d422c 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/RolesDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/RolesDto.cs @@ -6,7 +6,6 @@ // ========================================================================== using Squidex.Domain.Apps.Entities.Apps; -using Squidex.Infrastructure.Validation; using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Apps.Models; @@ -16,7 +15,6 @@ public sealed class RolesDto : Resource /// /// The roles. /// - [LocalizedRequired] public RoleDto[] Items { get; set; } public static RolesDto FromDomain(IAppEntity app, Resources resources) diff --git a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/TransferToTeamDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/TransferToTeamDto.cs index f0561bac9..41a3bb8b2 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/TransferToTeamDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/TransferToTeamDto.cs @@ -8,9 +8,11 @@ using Squidex.Domain.Apps.Entities.Apps.Commands; using Squidex.Infrastructure; using Squidex.Infrastructure.Reflection; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Apps.Models; +[OpenApiRequest] public sealed class TransferToTeamDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/UpdateAppDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/UpdateAppDto.cs index fa31d72d1..f2946b4d3 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/UpdateAppDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/UpdateAppDto.cs @@ -7,9 +7,11 @@ using Squidex.Domain.Apps.Entities.Apps.Commands; using Squidex.Infrastructure.Reflection; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Apps.Models; +[OpenApiRequest] public sealed class UpdateAppDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/UpdateAppSettingsDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/UpdateAppSettingsDto.cs index 36ae9c056..28b6cc35b 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/UpdateAppSettingsDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/UpdateAppSettingsDto.cs @@ -9,21 +9,24 @@ using System.ComponentModel.DataAnnotations; using Squidex.Domain.Apps.Core.Apps; using Squidex.Domain.Apps.Entities.Apps.Commands; using Squidex.Infrastructure.Collections; +using Squidex.Infrastructure.Validation; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Apps.Models; +[OpenApiRequest] public sealed class UpdateAppSettingsDto { /// /// The configured app patterns. /// - [Required] + [LocalizedRequired] public PatternDto[] Patterns { get; set; } /// /// The configured UI editors. /// - [Required] + [LocalizedRequired] public EditorDto[] Editors { get; set; } /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/UpdateAssetScriptsDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/UpdateAssetScriptsDto.cs index 1fc54262e..92e301967 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/UpdateAssetScriptsDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/UpdateAssetScriptsDto.cs @@ -8,9 +8,11 @@ using Squidex.Domain.Apps.Core.Assets; using Squidex.Domain.Apps.Entities.Apps.Commands; using Squidex.Infrastructure.Reflection; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Apps.Models; +[OpenApiRequest] public sealed class UpdateAssetScriptsDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/UpdateClientDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/UpdateClientDto.cs index 062d1d5bf..8cff5e0ca 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/UpdateClientDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/UpdateClientDto.cs @@ -8,9 +8,11 @@ using Squidex.Domain.Apps.Entities.Apps.Commands; using Squidex.Infrastructure.Reflection; using Squidex.Infrastructure.Validation; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Apps.Models; +[OpenApiRequest] public sealed class UpdateClientDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/UpdateLanguageDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/UpdateLanguageDto.cs index b75ff187e..1e733a52e 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/UpdateLanguageDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/UpdateLanguageDto.cs @@ -8,9 +8,11 @@ using Squidex.Domain.Apps.Entities.Apps.Commands; using Squidex.Infrastructure; using Squidex.Infrastructure.Reflection; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Apps.Models; +[OpenApiRequest] public sealed class UpdateLanguageDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/UpdateRoleDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/UpdateRoleDto.cs index 48f270435..6c65d03cb 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/UpdateRoleDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/UpdateRoleDto.cs @@ -9,9 +9,11 @@ using Squidex.Domain.Apps.Entities.Apps.Commands; using Squidex.Infrastructure.Json.Objects; using Squidex.Infrastructure.Reflection; using Squidex.Infrastructure.Validation; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Apps.Models; +[OpenApiRequest] public sealed class UpdateRoleDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/UpdateWorkflowDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/UpdateWorkflowDto.cs index d3e6c30c2..38cc6bbb0 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/UpdateWorkflowDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/UpdateWorkflowDto.cs @@ -10,9 +10,11 @@ using Squidex.Domain.Apps.Entities.Apps.Commands; using Squidex.Infrastructure; using Squidex.Infrastructure.Collections; using Squidex.Infrastructure.Validation; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Apps.Models; +[OpenApiRequest] public sealed class UpdateWorkflowDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/WorkflowDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/WorkflowDto.cs index 5db550625..f53e5768f 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/WorkflowDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/WorkflowDto.cs @@ -14,6 +14,7 @@ using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Apps.Models; +[OpenApiRequest] public sealed class WorkflowDto : Resource { /// @@ -29,7 +30,6 @@ public sealed class WorkflowDto : Resource /// /// The workflow steps. /// - [LocalizedRequired] public Dictionary Steps { get; set; } /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/WorkflowStepDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/WorkflowStepDto.cs index 5bf48be96..245d01c62 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/WorkflowStepDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/WorkflowStepDto.cs @@ -9,16 +9,17 @@ using Squidex.Domain.Apps.Core.Contents; using Squidex.Infrastructure.Collections; using Squidex.Infrastructure.Reflection; using Squidex.Infrastructure.Validation; +using Squidex.Web; using NoUpdateType = Squidex.Domain.Apps.Core.Contents.NoUpdate; namespace Squidex.Areas.Api.Controllers.Apps.Models; +[OpenApiRequest] public sealed class WorkflowStepDto { /// /// The transitions. /// - [LocalizedRequired] public Dictionary Transitions { get; set; } /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/WorkflowsDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/WorkflowsDto.cs index 66752456c..a6f36d8f5 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/WorkflowsDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/WorkflowsDto.cs @@ -7,7 +7,6 @@ using Squidex.Domain.Apps.Entities.Apps; using Squidex.Domain.Apps.Entities.Contents; -using Squidex.Infrastructure.Validation; using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Apps.Models; @@ -17,13 +16,11 @@ public sealed class WorkflowsDto : Resource /// /// The workflow. /// - [LocalizedRequired] public WorkflowDto[] Items { get; set; } /// /// The errros that should be fixed. /// - [LocalizedRequired] public string[] Errors { get; set; } public static async Task FromAppAsync(IWorkflowsValidator workflowsValidator, IAppEntity app, Resources resources) diff --git a/backend/src/Squidex/Areas/Api/Controllers/Assets/AssetFoldersController.cs b/backend/src/Squidex/Areas/Api/Controllers/Assets/AssetFoldersController.cs index 4060bbdf5..27fe42245 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Assets/AssetFoldersController.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Assets/AssetFoldersController.cs @@ -49,11 +49,31 @@ public sealed class AssetFoldersController : ApiController [ProducesResponseType(typeof(AssetFoldersDto), StatusCodes.Status200OK)] [ApiPermissionOrAnonymous(PermissionIds.AppAssetsRead)] [ApiCosts(1)] - public async Task GetAssetFolders(string app, [FromQuery] DomainId parentId, [FromQuery] AssetFolderScope scope = AssetFolderScope.PathAndItems) + public async Task GetAssetFolders(string app, [FromQuery] DomainId? parentId, [FromQuery] AssetFolderScope scope = AssetFolderScope.PathAndItems) { + Task> GetAssetPathAsync() + { + if (scope == AssetFolderScope.Items || parentId == null) + { + return Task.FromResult>(ReadonlyList.Empty()); + } + + return assetQuery.FindAssetFolderAsync(Context.App.Id, parentId.Value, HttpContext.RequestAborted); + } + + Task> GetAssetFoldersAsync() + { + if (scope == AssetFolderScope.Path) + { + return Task.FromResult(ResultList.Empty()); + } + + return assetQuery.QueryAssetFoldersAsync(Context, parentId, HttpContext.RequestAborted); + } + var (folders, path) = await AsyncHelper.WhenAll( - GetAssetFoldersAsync(parentId, scope), - GetAssetPathAsync(parentId, scope)); + GetAssetFoldersAsync(), + GetAssetPathAsync()); var response = Deferred.Response(() => { @@ -163,24 +183,4 @@ public sealed class AssetFoldersController : ApiController return AssetFolderDto.FromDomain(context.Result(), Resources); } - - private Task> GetAssetPathAsync(DomainId parentId, AssetFolderScope scope) - { - if (scope == AssetFolderScope.Items) - { - return Task.FromResult>(ReadonlyList.Empty()); - } - - return assetQuery.FindAssetFolderAsync(Context.App.Id, parentId, HttpContext.RequestAborted); - } - - private Task> GetAssetFoldersAsync(DomainId parentId, AssetFolderScope scope) - { - if (scope == AssetFolderScope.Path) - { - return Task.FromResult(ResultList.Empty()); - } - - return assetQuery.QueryAssetFoldersAsync(Context, parentId, HttpContext.RequestAborted); - } } diff --git a/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/AnnotateAssetDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/AnnotateAssetDto.cs index f9393ba5a..cd9c29edf 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/AnnotateAssetDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/AnnotateAssetDto.cs @@ -9,9 +9,11 @@ using Squidex.Domain.Apps.Core.Assets; using Squidex.Domain.Apps.Entities.Assets.Commands; using Squidex.Infrastructure; using Squidex.Infrastructure.Reflection; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Assets.Models; +[OpenApiRequest] public sealed class AnnotateAssetDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/AssetDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/AssetDto.cs index a2dfe2f6b..7bf991eed 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/AssetDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/AssetDto.cs @@ -31,7 +31,6 @@ public sealed class AssetDto : Resource /// /// The file name. /// - [LocalizedRequired] public string FileName { get; set; } /// @@ -47,25 +46,21 @@ public sealed class AssetDto : Resource /// /// The slug. /// - [LocalizedRequired] public string Slug { get; set; } /// /// The mime type. /// - [LocalizedRequired] public string MimeType { get; set; } /// /// The file type. /// - [LocalizedRequired] public string FileType { get; set; } /// /// The formatted text representation of the metadata. /// - [LocalizedRequired] public string MetadataText { get; set; } /// @@ -76,13 +71,11 @@ public sealed class AssetDto : Resource /// /// The asset metadata. /// - [LocalizedRequired] public AssetMetadata Metadata { get; set; } /// /// The asset tags. /// - [LocalizedRequired] public HashSet? Tags { get; set; } /// @@ -103,13 +96,11 @@ public sealed class AssetDto : Resource /// /// The user that has created the schema. /// - [LocalizedRequired] public RefToken CreatedBy { get; set; } /// /// The user that has updated the asset. /// - [LocalizedRequired] public RefToken LastModifiedBy { get; set; } /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/AssetFolderDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/AssetFolderDto.cs index 0340c0cfb..39ac4992b 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/AssetFolderDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/AssetFolderDto.cs @@ -28,7 +28,6 @@ public sealed class AssetFolderDto : Resource /// /// The folder name. /// - [LocalizedRequired] public string FolderName { get; set; } /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/AssetFoldersDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/AssetFoldersDto.cs index 5233cc10a..8f7035bf2 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/AssetFoldersDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/AssetFoldersDto.cs @@ -22,13 +22,11 @@ public sealed class AssetFoldersDto : Resource /// /// The assets folders. /// - [LocalizedRequired] public AssetFolderDto[] Items { get; set; } /// /// The path to the current folder. /// - [LocalizedRequired] public AssetFolderDto[] Path { get; set; } public static AssetFoldersDto FromDomain(IResultList assetFolders, IEnumerable path, Resources resources) diff --git a/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/AssetsDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/AssetsDto.cs index 4efa4b699..86624077a 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/AssetsDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/AssetsDto.cs @@ -22,7 +22,6 @@ public sealed class AssetsDto : Resource /// /// The assets. /// - [LocalizedRequired] public AssetDto[] Items { get; set; } public static AssetsDto FromDomain(IResultList assets, Resources resources) diff --git a/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/BulkUpdateAssetsDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/BulkUpdateAssetsDto.cs index 51afdbb16..e6bc4781e 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/BulkUpdateAssetsDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/BulkUpdateAssetsDto.cs @@ -8,15 +8,16 @@ using Squidex.Domain.Apps.Entities.Assets.Commands; using Squidex.Infrastructure.Reflection; using Squidex.Infrastructure.Validation; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Assets.Models; +[OpenApiRequest] public sealed class BulkUpdateAssetsDto { /// /// The contents to update or insert. /// - [LocalizedRequired] public BulkUpdateAssetsJobDto[]? Jobs { get; set; } /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/BulkUpdateAssetsJobDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/BulkUpdateAssetsJobDto.cs index 51e4c4a7f..c8dd4ee10 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/BulkUpdateAssetsJobDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/BulkUpdateAssetsJobDto.cs @@ -9,9 +9,11 @@ using Squidex.Domain.Apps.Core.Assets; using Squidex.Domain.Apps.Entities.Assets.Commands; using Squidex.Infrastructure; using Squidex.Infrastructure.Reflection; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Assets.Models; +[OpenApiRequest] public class BulkUpdateAssetsJobDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/CreateAssetDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/CreateAssetDto.cs index 51ff124ca..e7a77391c 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/CreateAssetDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/CreateAssetDto.cs @@ -10,9 +10,11 @@ using Squidex.Assets; using Squidex.Domain.Apps.Entities.Assets.Commands; using Squidex.Infrastructure; using Squidex.Infrastructure.Reflection; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Assets.Models; +[OpenApiRequest] public sealed class CreateAssetDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/CreateAssetFolderDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/CreateAssetFolderDto.cs index 8fb230ff2..6f509a3e7 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/CreateAssetFolderDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/CreateAssetFolderDto.cs @@ -9,9 +9,11 @@ using Squidex.Domain.Apps.Entities.Assets.Commands; using Squidex.Infrastructure; using Squidex.Infrastructure.Reflection; using Squidex.Infrastructure.Validation; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Assets.Models; +[OpenApiRequest] public sealed class CreateAssetFolderDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/DeleteAssetDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/DeleteAssetDto.cs index dde019897..192de45c2 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/DeleteAssetDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/DeleteAssetDto.cs @@ -9,9 +9,11 @@ using Microsoft.AspNetCore.Mvc; using Squidex.Domain.Apps.Entities.Assets.Commands; using Squidex.Infrastructure; using Squidex.Infrastructure.Reflection; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Assets.Models; +[OpenApiRequest] public sealed class DeleteAssetDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/MoveAssetDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/MoveAssetDto.cs index 26d58844a..b21bbc259 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/MoveAssetDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/MoveAssetDto.cs @@ -8,9 +8,11 @@ using Squidex.Domain.Apps.Entities.Assets.Commands; using Squidex.Infrastructure; using Squidex.Infrastructure.Reflection; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Assets.Models; +[OpenApiRequest] public sealed class MoveAssetDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/MoveAssetFolderDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/MoveAssetFolderDto.cs index 396ca0d0f..7b07cf6f0 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/MoveAssetFolderDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/MoveAssetFolderDto.cs @@ -8,9 +8,11 @@ using Squidex.Domain.Apps.Entities.Assets.Commands; using Squidex.Infrastructure; using Squidex.Infrastructure.Reflection; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Assets.Models; +[OpenApiRequest] public sealed class MoveAssetFolderDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/RenameAssetFolderDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/RenameAssetFolderDto.cs index a5f2853c5..25bab82f9 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/RenameAssetFolderDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/RenameAssetFolderDto.cs @@ -9,9 +9,11 @@ using Squidex.Domain.Apps.Entities.Assets.Commands; using Squidex.Infrastructure; using Squidex.Infrastructure.Reflection; using Squidex.Infrastructure.Validation; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Assets.Models; +[OpenApiRequest] public sealed class RenameAssetFolderDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/UpsertAssetDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/UpsertAssetDto.cs index 48fe38b90..92fe72427 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/UpsertAssetDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/UpsertAssetDto.cs @@ -10,9 +10,11 @@ using Squidex.Assets; using Squidex.Domain.Apps.Entities.Assets.Commands; using Squidex.Infrastructure; using Squidex.Infrastructure.Reflection; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Assets.Models; +[OpenApiRequest] public sealed class UpsertAssetDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/AssignContributorDto.cs b/backend/src/Squidex/Areas/Api/Controllers/AssignContributorDto.cs index 8132e9878..4fa0fdd23 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/AssignContributorDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/AssignContributorDto.cs @@ -6,10 +6,12 @@ // ========================================================================== using Squidex.Infrastructure.Validation; +using Squidex.Web; using Roles = Squidex.Domain.Apps.Core.Apps.Role; namespace Squidex.Areas.Api.Controllers; +[OpenApiRequest] public sealed class AssignContributorDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Backups/Models/BackupJobsDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Backups/Models/BackupJobsDto.cs index f354cf8ef..d43cf5606 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Backups/Models/BackupJobsDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Backups/Models/BackupJobsDto.cs @@ -6,7 +6,6 @@ // ========================================================================== using Squidex.Domain.Apps.Entities.Backup; -using Squidex.Infrastructure.Validation; using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Backups.Models; @@ -16,7 +15,6 @@ public sealed class BackupJobsDto : Resource /// /// The backups. /// - [LocalizedRequired] public BackupJobDto[] Items { get; set; } public static BackupJobsDto FromDomain(IEnumerable backups, Resources resources) diff --git a/backend/src/Squidex/Areas/Api/Controllers/Backups/Models/RestoreJobDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Backups/Models/RestoreJobDto.cs index 8af76c419..563eccc90 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Backups/Models/RestoreJobDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Backups/Models/RestoreJobDto.cs @@ -9,6 +9,7 @@ using NodaTime; using Squidex.Domain.Apps.Entities.Backup; using Squidex.Infrastructure.Reflection; using Squidex.Infrastructure.Validation; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Backups.Models; @@ -17,13 +18,11 @@ public sealed class RestoreJobDto /// /// The uri to load from. /// - [LocalizedRequired] public Uri Url { get; set; } /// /// The status log. /// - [LocalizedRequired] public List Log { get; set; } /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Backups/Models/RestoreRequestDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Backups/Models/RestoreRequestDto.cs index fc33f7ed8..562039c62 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Backups/Models/RestoreRequestDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Backups/Models/RestoreRequestDto.cs @@ -6,9 +6,11 @@ // ========================================================================== using Squidex.Infrastructure.Validation; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Backups.Models; +[OpenApiRequest] public sealed class RestoreRequestDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Comments/Models/CommentDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Comments/Models/CommentDto.cs index 4c2a1492f..bece5d04b 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Comments/Models/CommentDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Comments/Models/CommentDto.cs @@ -10,7 +10,6 @@ using Squidex.Domain.Apps.Core.Comments; using Squidex.Domain.Apps.Entities.Comments.Commands; using Squidex.Infrastructure; using Squidex.Infrastructure.Reflection; -using Squidex.Infrastructure.Validation; namespace Squidex.Areas.Api.Controllers.Comments.Models; @@ -24,19 +23,16 @@ public sealed class CommentDto /// /// The time when the comment was created or updated last. /// - [LocalizedRequired] public Instant Time { get; set; } /// /// The user who created or updated the comment. /// - [LocalizedRequired] public RefToken User { get; set; } /// /// The text of the comment. /// - [LocalizedRequired] public string Text { get; set; } /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Comments/Models/UpsertCommentDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Comments/Models/UpsertCommentDto.cs index 21024690b..0dfa2d6e9 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Comments/Models/UpsertCommentDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Comments/Models/UpsertCommentDto.cs @@ -9,9 +9,11 @@ using Squidex.Domain.Apps.Entities.Comments.Commands; using Squidex.Infrastructure; using Squidex.Infrastructure.Reflection; using Squidex.Infrastructure.Validation; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Comments.Models; +[OpenApiRequest] public sealed class UpsertCommentDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Contents/ContentsController.cs b/backend/src/Squidex/Areas/Api/Controllers/Contents/ContentsController.cs index cd8c80a9e..49d12768a 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Contents/ContentsController.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Contents/ContentsController.cs @@ -21,6 +21,7 @@ using Squidex.Web.Pipeline; namespace Squidex.Areas.Api.Controllers.Contents; [SchemaMustBePublished] +[ApiExplorerSettings(GroupName = nameof(Contents))] public sealed class ContentsController : ApiController { private readonly IContentQueryService contentQuery; diff --git a/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/AllContentsByGetDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/AllContentsByGetDto.cs index 279fad30d..b228e8810 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/AllContentsByGetDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/AllContentsByGetDto.cs @@ -11,9 +11,11 @@ using Squidex.Domain.Apps.Entities; using Squidex.Infrastructure; using Squidex.Infrastructure.Translations; using Squidex.Infrastructure.Validation; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Contents.Models; +[OpenApiRequest] public sealed class AllContentsByGetDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/AllContentsByPostDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/AllContentsByPostDto.cs index a33a57071..26c622981 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/AllContentsByPostDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/AllContentsByPostDto.cs @@ -12,9 +12,11 @@ using Squidex.Domain.Apps.Entities; using Squidex.Infrastructure; using Squidex.Infrastructure.Translations; using Squidex.Infrastructure.Validation; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Contents.Models; +[OpenApiRequest] public sealed class AllContentsByPostDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/BulkUpdateContentsDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/BulkUpdateContentsDto.cs index 7a03546e3..b3506b598 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/BulkUpdateContentsDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/BulkUpdateContentsDto.cs @@ -9,9 +9,11 @@ using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Entities.Contents.Commands; using Squidex.Infrastructure.Reflection; using Squidex.Infrastructure.Validation; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Contents.Models; +[OpenApiRequest] public sealed class BulkUpdateContentsDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/BulkUpdateContentsJobDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/BulkUpdateContentsJobDto.cs index 7d29f59e7..f16713ec3 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/BulkUpdateContentsJobDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/BulkUpdateContentsJobDto.cs @@ -10,9 +10,11 @@ using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Entities.Contents.Commands; using Squidex.Infrastructure; using Squidex.Infrastructure.Reflection; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Contents.Models; +[OpenApiRequest] public class BulkUpdateContentsJobDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/ChangeStatusDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/ChangeStatusDto.cs index 1724fab54..746d916ac 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/ChangeStatusDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/ChangeStatusDto.cs @@ -11,9 +11,11 @@ using Squidex.Domain.Apps.Entities.Contents.Commands; using Squidex.Infrastructure; using Squidex.Infrastructure.Reflection; using Squidex.Infrastructure.Validation; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Contents.Models; +[OpenApiRequest] public sealed class ChangeStatusDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/ContentDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/ContentDto.cs index 60dd56255..5348770af 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/ContentDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/ContentDto.cs @@ -27,19 +27,16 @@ public sealed class ContentDto : Resource /// /// The user that has created the content item. /// - [LocalizedRequired] public RefToken CreatedBy { get; set; } /// /// The user that has updated the content item. /// - [LocalizedRequired] public RefToken LastModifiedBy { get; set; } /// /// The data of the content item. /// - [LocalizedRequired] public object Data { get; set; } /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/ContentsDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/ContentsDto.cs index 9909158c6..284572703 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/ContentsDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/ContentsDto.cs @@ -23,13 +23,11 @@ public sealed class ContentsDto : Resource /// /// The content items. /// - [LocalizedRequired] public ContentDto[] Items { get; set; } /// /// The possible statuses. /// - [LocalizedRequired] public StatusInfoDto[] Statuses { get; set; } public static async Task FromContentsAsync(IResultList contents, Resources resources, diff --git a/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/ImportContentsDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/ImportContentsDto.cs index 23a346af0..416af03b6 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/ImportContentsDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/ImportContentsDto.cs @@ -9,9 +9,11 @@ using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Entities.Contents.Commands; using Squidex.Infrastructure.Reflection; using Squidex.Infrastructure.Validation; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Contents.Models; +[OpenApiRequest] public sealed class ImportContentsDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/ScheduleJobDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/ScheduleJobDto.cs index 307234a7d..b1de3a709 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/ScheduleJobDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/ScheduleJobDto.cs @@ -37,6 +37,5 @@ public sealed class ScheduleJobDto /// /// The user who schedule the content. /// - [LocalizedRequired] public RefToken ScheduledBy { get; set; } } diff --git a/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/StatusInfoDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/StatusInfoDto.cs index 7206b4d1e..e0b48863d 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/StatusInfoDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/StatusInfoDto.cs @@ -15,13 +15,11 @@ public sealed class StatusInfoDto /// /// The name of the status. /// - [LocalizedRequired] public Status Status { get; set; } /// /// The color of the status. /// - [LocalizedRequired] public string Color { get; set; } public static StatusInfoDto FromDomain(StatusInfo statusInfo) diff --git a/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/UpsertContentDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/UpsertContentDto.cs index 96cd69c51..08984499e 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/UpsertContentDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/UpsertContentDto.cs @@ -10,10 +10,12 @@ using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Entities.Contents.Commands; using Squidex.Infrastructure; using Squidex.Infrastructure.Reflection; +using Squidex.Web; using StatusType = Squidex.Domain.Apps.Core.Contents.Status; namespace Squidex.Areas.Api.Controllers.Contents.Models; +[OpenApiRequest] public class UpsertContentDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/ContributorDto.cs b/backend/src/Squidex/Areas/Api/Controllers/ContributorDto.cs index 3c86e5109..e346bdf40 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/ContributorDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/ContributorDto.cs @@ -20,19 +20,16 @@ public sealed class ContributorDto : Resource /// /// The ID of the user that contributes to the app. /// - [LocalizedRequired] public string ContributorId { get; set; } /// /// The display name. /// - [LocalizedRequired] public string ContributorName { get; set; } /// /// The email address. /// - [LocalizedRequired] public string ContributorEmail { get; set; } /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/ContributorsDto.cs b/backend/src/Squidex/Areas/Api/Controllers/ContributorsDto.cs index cd0319aea..31868638f 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/ContributorsDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/ContributorsDto.cs @@ -22,7 +22,6 @@ public sealed class ContributorsDto : Resource /// /// The contributors. /// - [LocalizedRequired] public ContributorDto[] Items { get; set; } /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/History/Models/HistoryEventDto.cs b/backend/src/Squidex/Areas/Api/Controllers/History/Models/HistoryEventDto.cs index 2d20248b3..bf3f70ceb 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/History/Models/HistoryEventDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/History/Models/HistoryEventDto.cs @@ -18,19 +18,16 @@ public sealed class HistoryEventDto /// /// The message for the event. /// - [LocalizedRequired] public string Message { get; set; } /// /// The type of the original event. /// - [LocalizedRequired] public string EventType { get; set; } /// /// The user who called the action. /// - [LocalizedRequired] public string Actor { get; set; } /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/LanguageDto.cs b/backend/src/Squidex/Areas/Api/Controllers/LanguageDto.cs index 69737fcb7..2122952dd 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/LanguageDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/LanguageDto.cs @@ -16,19 +16,16 @@ public sealed class LanguageDto /// /// The iso code of the language. /// - [LocalizedRequired] public string Iso2Code { get; set; } /// /// The english name of the language. /// - [LocalizedRequired] public string EnglishName { get; set; } /// /// The native name of the language. /// - [LocalizedRequired] public string NativeName { get; set; } public static LanguageDto FromDomain(Language language) diff --git a/backend/src/Squidex/Areas/Api/Controllers/News/Models/FeatureDto.cs b/backend/src/Squidex/Areas/Api/Controllers/News/Models/FeatureDto.cs index 80c66a994..76107f871 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/News/Models/FeatureDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/News/Models/FeatureDto.cs @@ -14,12 +14,10 @@ public sealed class FeatureDto /// /// The name of the feature. /// - [LocalizedRequired] public string Name { get; set; } /// /// The description text. /// - [LocalizedRequired] public string Text { get; set; } } diff --git a/backend/src/Squidex/Areas/Api/Controllers/News/Models/FeaturesDto.cs b/backend/src/Squidex/Areas/Api/Controllers/News/Models/FeaturesDto.cs index f25f84f51..abedbd2e0 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/News/Models/FeaturesDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/News/Models/FeaturesDto.cs @@ -14,7 +14,6 @@ public class FeaturesDto /// /// The latest features. /// - [LocalizedRequired] public List Features { get; } = new List(); /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Plans/Models/ChangePlanDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Plans/Models/ChangePlanDto.cs index 7b30b256c..30250aed5 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Plans/Models/ChangePlanDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Plans/Models/ChangePlanDto.cs @@ -6,9 +6,11 @@ // ========================================================================== using Squidex.Infrastructure.Validation; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Plans.Models; +[OpenApiRequest] public sealed class ChangePlanDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Plans/Models/PlanDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Plans/Models/PlanDto.cs index b849f4661..71a5c9cca 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Plans/Models/PlanDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Plans/Models/PlanDto.cs @@ -16,19 +16,16 @@ public sealed class PlanDto /// /// The ID of the plan. /// - [LocalizedRequired] public string Id { get; set; } /// /// The name of the plan. /// - [LocalizedRequired] public string Name { get; set; } /// /// The monthly costs of the plan. /// - [LocalizedRequired] public string Costs { get; set; } /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Plans/Models/PlansDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Plans/Models/PlansDto.cs index ccee5e311..617b790d8 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Plans/Models/PlansDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Plans/Models/PlansDto.cs @@ -15,7 +15,6 @@ public sealed class PlansDto /// /// The available plans. /// - [LocalizedRequired] public PlanDto[] Plans { get; set; } /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/RenameTagDto.cs b/backend/src/Squidex/Areas/Api/Controllers/RenameTagDto.cs index 3e8ebebe8..d22b85458 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/RenameTagDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/RenameTagDto.cs @@ -6,9 +6,11 @@ // ========================================================================== using Squidex.Infrastructure.Validation; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers; +[OpenApiRequest] public sealed class RenameTagDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/CreateRuleDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/CreateRuleDto.cs index 0bc991074..b483026d6 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/CreateRuleDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/CreateRuleDto.cs @@ -8,9 +8,11 @@ using Squidex.Domain.Apps.Core.Rules; using Squidex.Domain.Apps.Entities.Rules.Commands; using Squidex.Infrastructure.Validation; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Rules.Models; +[OpenApiRequest] public sealed class CreateRuleDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/RuleDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/RuleDto.cs index 964841ec3..3cd1b4b45 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/RuleDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/RuleDto.cs @@ -27,13 +27,11 @@ public sealed class RuleDto : Resource /// /// The user that has created the rule. /// - [LocalizedRequired] public RefToken CreatedBy { get; set; } /// /// The user that has updated the rule. /// - [LocalizedRequired] public RefToken LastModifiedBy { get; set; } /// @@ -64,13 +62,11 @@ public sealed class RuleDto : Resource /// /// The trigger properties. /// - [LocalizedRequired] public RuleTriggerDto Trigger { get; set; } /// /// The action properties. /// - [LocalizedRequired] public RuleAction Action { get; set; } /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/RuleElementDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/RuleElementDto.cs index 95aaa52b5..2ecc1523a 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/RuleElementDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/RuleElementDto.cs @@ -16,13 +16,11 @@ public sealed class RuleElementDto /// /// Describes the action or trigger type. /// - [LocalizedRequired] public string Description { get; set; } /// /// The label for the action or trigger type. /// - [LocalizedRequired] public string Display { get; set; } /// @@ -48,7 +46,6 @@ public sealed class RuleElementDto /// /// The properties. /// - [LocalizedRequired] public RuleElementPropertyDto[] Properties { get; set; } public static RuleElementDto FromDomain(RuleActionDefinition definition) diff --git a/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/RuleElementPropertyDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/RuleElementPropertyDto.cs index c8cde27c4..0c143647c 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/RuleElementPropertyDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/RuleElementPropertyDto.cs @@ -15,19 +15,16 @@ public sealed class RuleElementPropertyDto /// /// The html editor. /// - [LocalizedRequired] public RuleFieldEditor Editor { get; set; } /// /// The name of the editor. /// - [LocalizedRequired] public string Name { get; set; } /// /// The label to use. /// - [LocalizedRequired] public string Display { get; set; } /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/RuleEventDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/RuleEventDto.cs index b85f4585b..143040e13 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/RuleEventDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/RuleEventDto.cs @@ -30,13 +30,11 @@ public sealed class RuleEventDto : Resource /// /// The description. /// - [LocalizedRequired] public string Description { get; set; } /// /// The name of the event. /// - [LocalizedRequired] public string EventName { get; set; } /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/RuleEventsDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/RuleEventsDto.cs index fef750ad8..b6738a2ef 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/RuleEventsDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/RuleEventsDto.cs @@ -15,15 +15,14 @@ namespace Squidex.Areas.Api.Controllers.Rules.Models; public sealed class RuleEventsDto : Resource { /// - /// The rule events. + /// The total number of rule events. /// - [LocalizedRequired] - public RuleEventDto[] Items { get; set; } + public long Total { get; set; } /// - /// The total number of rule events. + /// The rule events. /// - public long Total { get; set; } + public RuleEventDto[] Items { get; set; } public static RuleEventsDto FromDomain(IResultList ruleEvents, Resources resources, DomainId? ruleId) { diff --git a/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/RulesDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/RulesDto.cs index ec2ac1143..b2d0af4ab 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/RulesDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/RulesDto.cs @@ -18,7 +18,6 @@ public sealed class RulesDto : Resource /// /// The rules. /// - [LocalizedRequired] public RuleDto[] Items { get; set; } /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/SimulatedRuleEventsDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/SimulatedRuleEventsDto.cs index af1231e1c..291c8e33f 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/SimulatedRuleEventsDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/SimulatedRuleEventsDto.cs @@ -14,15 +14,14 @@ namespace Squidex.Areas.Api.Controllers.Rules.Models; public sealed class SimulatedRuleEventsDto : Resource { /// - /// The simulated rule events. + /// The total number of simulated rule events. /// - [LocalizedRequired] - public SimulatedRuleEventDto[] Items { get; set; } + public long Total { get; set; } /// - /// The total number of simulated rule events. + /// The simulated rule events. /// - public long Total { get; set; } + public SimulatedRuleEventDto[] Items { get; set; } public static SimulatedRuleEventsDto FromDomain(IList events) { diff --git a/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/UpdateRuleDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/UpdateRuleDto.cs index db94debde..6531c7798 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/UpdateRuleDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/UpdateRuleDto.cs @@ -9,9 +9,11 @@ using Squidex.Domain.Apps.Core.Rules; using Squidex.Domain.Apps.Entities.Rules.Commands; using Squidex.Infrastructure; using Squidex.Infrastructure.Reflection; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Rules.Models; +[OpenApiRequest] public sealed class UpdateRuleDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/AddFieldDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/AddFieldDto.cs index 50605073c..7388137e8 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/AddFieldDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/AddFieldDto.cs @@ -8,9 +8,11 @@ using Squidex.Domain.Apps.Entities.Schemas.Commands; using Squidex.Infrastructure.Reflection; using Squidex.Infrastructure.Validation; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Schemas.Models; +[OpenApiRequest] public sealed class AddFieldDto { /// @@ -35,4 +37,4 @@ public sealed class AddFieldDto { return SimpleMapper.Map(this, new AddField { ParentFieldId = parentId, Properties = Properties.ToProperties() }); } -} \ No newline at end of file +} diff --git a/backend/src/Squidex/Areas/Api/Controllers/Search/Models/SearchResultDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Search/Models/SearchResultDto.cs index 408c28325..35a7fa309 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Search/Models/SearchResultDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Search/Models/SearchResultDto.cs @@ -17,13 +17,11 @@ public class SearchResultDto : Resource /// /// The name of the search result. /// - [LocalizedRequired] public string Name { get; set; } /// /// The type of the search result. /// - [LocalizedRequired] public SearchResultType Type { get; set; } /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Statistics/Models/CallsUsageDtoDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Statistics/Models/CallsUsageDtoDto.cs index a9bbcc82d..989158b6e 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Statistics/Models/CallsUsageDtoDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Statistics/Models/CallsUsageDtoDto.cs @@ -56,7 +56,6 @@ public sealed class CallsUsageDtoDto /// /// The statistics by date and group. /// - [LocalizedRequired] public Dictionary Details { get; set; } public static CallsUsageDtoDto FromDomain(Plan plan, ApiStatsSummary summary, Dictionary> details) diff --git a/backend/src/Squidex/Areas/Api/Controllers/Teams/Models/CreateTeamDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Teams/Models/CreateTeamDto.cs index fbe47314e..e8fb7480c 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Teams/Models/CreateTeamDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Teams/Models/CreateTeamDto.cs @@ -8,9 +8,11 @@ using Squidex.Domain.Apps.Entities.Teams.Commands; using Squidex.Infrastructure.Reflection; using Squidex.Infrastructure.Validation; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Teams.Models; +[OpenApiRequest] public sealed class CreateTeamDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Teams/Models/TeamDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Teams/Models/TeamDto.cs index f1b20f503..f41490fd5 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Teams/Models/TeamDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Teams/Models/TeamDto.cs @@ -28,7 +28,6 @@ public sealed class TeamDto : Resource /// /// The name of the team. /// - [LocalizedRequired] public string Name { get; set; } /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Teams/Models/UpdateTeamDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Teams/Models/UpdateTeamDto.cs index 613744178..b8e9800d9 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Teams/Models/UpdateTeamDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Teams/Models/UpdateTeamDto.cs @@ -8,9 +8,11 @@ using Squidex.Domain.Apps.Entities.Teams.Commands; using Squidex.Infrastructure.Reflection; using Squidex.Infrastructure.Validation; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Teams.Models; +[OpenApiRequest] public sealed class UpdateTeamDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Templates/Models/TemplateDetailsDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Templates/Models/TemplateDetailsDto.cs index 1dc1ca10a..7c8bdbe39 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Templates/Models/TemplateDetailsDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Templates/Models/TemplateDetailsDto.cs @@ -15,7 +15,6 @@ public class TemplateDetailsDto : Resource /// /// The details of the template. /// - [LocalizedRequired] public string Details { get; set; } public static TemplateDetailsDto FromDomain(string name, string details, Resources resources) diff --git a/backend/src/Squidex/Areas/Api/Controllers/Templates/Models/TemplateDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Templates/Models/TemplateDto.cs index 10657dfb3..ccec699e4 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Templates/Models/TemplateDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Templates/Models/TemplateDto.cs @@ -17,19 +17,16 @@ public sealed class TemplateDto : Resource /// /// The name of the template. /// - [LocalizedRequired] public string Name { get; set; } /// /// The title of the template. /// - [LocalizedRequired] public string Title { get; set; } /// /// The description of the template. /// - [LocalizedRequired] public string Description { get; set; } /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Translations/Models/TranslateDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Translations/Models/TranslateDto.cs index 8a3fdd408..a7a14a343 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Translations/Models/TranslateDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Translations/Models/TranslateDto.cs @@ -7,9 +7,11 @@ using Squidex.Infrastructure; using Squidex.Infrastructure.Validation; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Translations.Models; +[OpenApiRequest] public sealed class TranslateDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Users/Models/CreateUserDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Users/Models/CreateUserDto.cs index 321c48f65..4b609b897 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Users/Models/CreateUserDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Users/Models/CreateUserDto.cs @@ -8,9 +8,11 @@ using Squidex.Domain.Users; using Squidex.Infrastructure.Security; using Squidex.Infrastructure.Validation; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Users.Models; +[OpenApiRequest] public sealed class CreateUserDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Users/Models/UpdateUserDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Users/Models/UpdateUserDto.cs index 0a87004ef..f133bcb56 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Users/Models/UpdateUserDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Users/Models/UpdateUserDto.cs @@ -8,9 +8,11 @@ using Squidex.Domain.Users; using Squidex.Infrastructure.Security; using Squidex.Infrastructure.Validation; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Users.Models; +[OpenApiRequest] public sealed class UpdateUserDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Users/Models/UserDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Users/Models/UserDto.cs index f40b539a8..5eadfefe9 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Users/Models/UserDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Users/Models/UserDto.cs @@ -18,31 +18,26 @@ public sealed class UserDto : Resource /// /// The ID of the user. /// - [LocalizedRequired] public string Id { get; set; } /// /// The email of the user. Unique value. /// - [LocalizedRequired] public string Email { get; set; } /// /// The display name (usually first name and last name) of the user. /// - [LocalizedRequired] public string DisplayName { get; set; } /// /// Determines if the user is locked. /// - [LocalizedRequired] public bool IsLocked { get; set; } /// /// Additional permissions for the user. /// - [LocalizedRequired] public IEnumerable Permissions { get; set; } public static UserDto FromDomain(IUser user, Resources resources) diff --git a/backend/src/Squidex/Areas/Api/Controllers/Users/Models/UsersDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Users/Models/UsersDto.cs index e7e6b5ffe..15835ce81 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Users/Models/UsersDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Users/Models/UsersDto.cs @@ -21,7 +21,6 @@ public sealed class UsersDto : Resource /// /// The users. /// - [LocalizedRequired] public UserDto[] Items { get; set; } public static UsersDto FromDomain(IEnumerable items, long total, Resources resources) diff --git a/backend/tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/RolesJsonTests.cs b/backend/tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/RolesJsonTests.cs index e76c679a5..883c9d030 100644 --- a/backend/tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/RolesJsonTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/RolesJsonTests.cs @@ -49,7 +49,7 @@ public class RolesJsonTests new PermissionSet( "Permission1", "Permission2"), - new JsonObject() + JsonValue.Object() .Add("Property1", true) .Add("Property2", true)); diff --git a/backend/tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/RolesTests.cs b/backend/tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/RolesTests.cs index 820352838..e66b51244 100644 --- a/backend/tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/RolesTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/RolesTests.cs @@ -37,7 +37,7 @@ public class RolesTests { var roles_1 = roles_0.Add(role); - Assert.Equal(new Role(role, null, new JsonObject()), roles_1[role]); + Assert.Equal(new Role(role, null, JsonValue.Object()), roles_1[role]); } [Fact] @@ -68,9 +68,9 @@ public class RolesTests [Fact] public void Should_update_role_properties() { - var roles_1 = roles_0.Update(firstRole, properties: new JsonObject().Add("P1", true)); + var roles_1 = roles_0.Update(firstRole, properties: JsonValue.Object().Add("P1", true)); - roles_1[firstRole].Should().BeEquivalentTo(Role.WithProperties(firstRole, new JsonObject().Add("P1", true))); + roles_1[firstRole].Should().BeEquivalentTo(Role.WithProperties(firstRole, JsonValue.Object().Add("P1", true))); } [Fact] diff --git a/backend/tests/Squidex.Domain.Apps.Core.Tests/Model/Assets/AssetMetadataTests.cs b/backend/tests/Squidex.Domain.Apps.Core.Tests/Model/Assets/AssetMetadataTests.cs index f97d54c68..9a6df44bb 100644 --- a/backend/tests/Squidex.Domain.Apps.Core.Tests/Model/Assets/AssetMetadataTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Core.Tests/Model/Assets/AssetMetadataTests.cs @@ -96,9 +96,9 @@ public class AssetMetadataTests var sut = new AssetMetadata { ["meta"] = - new JsonObject() + JsonValue.Object() .Add("nested1", - new JsonObject() + JsonValue.Object() .Add("nested2", 12)) }; diff --git a/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/ContentConversionTests.cs b/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/ContentConversionTests.cs index d0dff0c9a..554547edc 100644 --- a/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/ContentConversionTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/ContentConversionTests.cs @@ -5,6 +5,7 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== +using Squidex.Domain.Apps.Core.Apps; using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.ConvertContent; using Squidex.Domain.Apps.Core.Schemas; @@ -16,6 +17,8 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent; public class ContentConversionTests { private readonly Schema schema; + private readonly LanguagesConfig languages = LanguagesConfig.English.Set(Language.DE); + private readonly Language language = Language.DE; private readonly ResolvedComponents components; public ContentConversionTests() @@ -51,33 +54,33 @@ public class ContentConversionTests new ContentFieldData() .AddInvariant( JsonValue.Array( - new JsonObject() + JsonValue.Object() .Add("nested", JsonValue.Array(1, 2))))) .AddField("component", new ContentFieldData() .AddInvariant( - new JsonObject() + JsonValue.Object() .Add("references", JsonValue.Array(1, 2)) .Add("assets1", JsonValue.Array(1)) .Add("array", JsonValue.Array( - new JsonObject() + JsonValue.Object() .Add("nested", JsonValue.Array(1, 2)))) .Add(Component.Discriminator, DomainId.Empty))) .AddField("components", new ContentFieldData() .AddInvariant( JsonValue.Array( - new JsonObject() + JsonValue.Object() .Add("references", JsonValue.Array(1, 2)) .Add("assets1", JsonValue.Array(1)) .Add("array", JsonValue.Array( - new JsonObject() + JsonValue.Object() .Add("nested", JsonValue.Array(1, 2)))) .Add(Component.Discriminator, DomainId.Empty)))); @@ -97,27 +100,27 @@ public class ContentConversionTests new ContentFieldData() .AddInvariant( JsonValue.Array( - new JsonObject()))) + JsonValue.Object()))) .AddField("component", new ContentFieldData() .AddInvariant( - new JsonObject() + JsonValue.Object() .Add("assets1", JsonValue.Array(1)) .Add("array", JsonValue.Array( - new JsonObject())) + JsonValue.Object())) .Add(Component.Discriminator, DomainId.Empty))) .AddField("components", new ContentFieldData() .AddInvariant( JsonValue.Array( - new JsonObject() + JsonValue.Object() .Add("assets1", JsonValue.Array(1)) .Add("array", JsonValue.Array( - new JsonObject())) + JsonValue.Object())) .Add(Component.Discriminator, DomainId.Empty)))); Assert.Equal(expected, actual); @@ -138,33 +141,33 @@ public class ContentConversionTests new ContentFieldData() .AddInvariant( JsonValue.Array( - new JsonObject() + JsonValue.Object() .Add("nested", JsonValue.Array(1, 2))))) .AddField("component", new ContentFieldData() .AddInvariant( - new JsonObject() + JsonValue.Object() .Add("references", JsonValue.Array(1, 2)) .Add("assets1", JsonValue.Array(1)) .Add("array", JsonValue.Array( - new JsonObject() + JsonValue.Object() .Add("nested", JsonValue.Array(1, 2)))) .Add(Component.Discriminator, DomainId.Empty))) .AddField("components", new ContentFieldData() .AddInvariant( JsonValue.Array( - new JsonObject() + JsonValue.Object() .Add("references", JsonValue.Array(1, 2)) .Add("assets1", JsonValue.Array(1)) .Add("array", JsonValue.Array( - new JsonObject() + JsonValue.Object() .Add("nested", JsonValue.Array(1, 2)))) .Add(Component.Discriminator, DomainId.Empty)))); @@ -185,13 +188,13 @@ public class ContentConversionTests new ContentFieldData() .AddInvariant( JsonValue.Array( - new JsonObject() + JsonValue.Object() .Add("extraField", 42) .Add("nested", JsonValue.Array(1, 2))))) .AddField("component", new ContentFieldData() .AddInvariant( - new JsonObject() + JsonValue.Object() .Add("extraField", 42) .Add("references", JsonValue.Array(1, 2)) @@ -199,7 +202,7 @@ public class ContentConversionTests JsonValue.Array(1)) .Add("array", JsonValue.Array( - new JsonObject() + JsonValue.Object() .Add("extraField", 42) .Add("nested", JsonValue.Array(1, 2)))) .Add(Component.Discriminator, DomainId.Empty))) @@ -207,7 +210,7 @@ public class ContentConversionTests new ContentFieldData() .AddInvariant( JsonValue.Array( - new JsonObject() + JsonValue.Object() .Add("extraField", 42) .Add("references", JsonValue.Array(1, 2)) @@ -215,7 +218,7 @@ public class ContentConversionTests JsonValue.Array(1)) .Add("array", JsonValue.Array( - new JsonObject() + JsonValue.Object() .Add("extraField", 42) .Add("nested", JsonValue.Array(1, 2)))) .Add(Component.Discriminator, DomainId.Empty)))); @@ -225,7 +228,7 @@ public class ContentConversionTests private sealed class ItemConverter : IContentItemConverter { - public JsonObject ConvertItem(IField field, JsonObject source) + public JsonObject ConvertItemAfter(IField field, JsonObject source, IEnumerable schema) { source["extraField"] = 42; diff --git a/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/DefaultValues/DefaultValuesTests.cs b/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/DefaultValueFactoryTests.cs similarity index 80% rename from backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/DefaultValues/DefaultValuesTests.cs rename to backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/DefaultValueFactoryTests.cs index 4188b6920..c388fa6d3 100644 --- a/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/DefaultValues/DefaultValuesTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/DefaultValueFactoryTests.cs @@ -6,78 +6,18 @@ // ========================================================================== using NodaTime; -using Squidex.Domain.Apps.Core.Apps; -using Squidex.Domain.Apps.Core.Contents; -using Squidex.Domain.Apps.Core.DefaultValues; +using Squidex.Domain.Apps.Core.ConvertContent; using Squidex.Domain.Apps.Core.Schemas; using Squidex.Infrastructure; using Squidex.Infrastructure.Collections; using Squidex.Infrastructure.Json.Objects; -namespace Squidex.Domain.Apps.Core.Operations.DefaultValues; +namespace Squidex.Domain.Apps.Core.Operations.ConvertContent; -public class DefaultValuesTests +public class DefaultValueFactoryTests { private readonly Instant now = Instant.FromUtc(2017, 10, 12, 16, 30, 10); - private readonly LanguagesConfig languages = LanguagesConfig.English.Set(Language.DE); private readonly Language language = Language.DE; - private readonly Schema schema; - - public DefaultValuesTests() - { - schema = - new Schema("my-schema") - .AddString(1, "myString", Partitioning.Language, - new StringFieldProperties { DefaultValue = "en-string" }) - .AddNumber(2, "myNumber", Partitioning.Invariant, - new NumberFieldProperties()) - .AddDateTime(3, "myDatetime", Partitioning.Invariant, - new DateTimeFieldProperties { DefaultValue = now }) - .AddBoolean(4, "myBoolean", Partitioning.Invariant, - new BooleanFieldProperties { DefaultValue = true }); - } - - [Fact] - public void Should_enrich_with_default_values() - { - var data = - new ContentData() - .AddField("myString", - new ContentFieldData() - .AddLocalized("de", "de-string")) - .AddField("myNumber", - new ContentFieldData() - .AddInvariant(456)); - - data.GenerateDefaultValues(schema, languages.ToResolver()); - - Assert.Equal(456, data["myNumber"]!["iv"].AsNumber); - - Assert.Equal("de-string", data["myString"]!["de"].AsString); - Assert.Equal("en-string", data["myString"]!["en"].AsString); - - Assert.Equal(now.ToString(), data["myDatetime"]!["iv"].AsString); - - Assert.True(data["myBoolean"]!["iv"].AsBoolean); - } - - [Fact] - public void Should_not_enrich_with_default_values_if_string_is_empty() - { - var data = - new ContentData() - .AddField("myString", - new ContentFieldData() - .AddLocalized("de", string.Empty)) - .AddField("myNumber", - new ContentFieldData() - .AddInvariant(456)); - - data.GenerateDefaultValues(schema, languages.ToResolver()); - - Assert.Equal(string.Empty, data["myString"]!["de"].AsString); - Assert.Equal("en-string", data["myString"]!["en"].AsString); - } [Fact] public void Should_get_default_value_from_assets_field() diff --git a/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/DefaultValuesTests.cs b/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/DefaultValuesTests.cs new file mode 100644 index 000000000..f8068b469 --- /dev/null +++ b/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/DefaultValuesTests.cs @@ -0,0 +1,207 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using NodaTime; +using Squidex.Domain.Apps.Core.Apps; +using Squidex.Domain.Apps.Core.Contents; +using Squidex.Domain.Apps.Core.ConvertContent; +using Squidex.Domain.Apps.Core.Schemas; +using Squidex.Infrastructure; +using Squidex.Infrastructure.Json.Objects; + +namespace Squidex.Domain.Apps.Core.Operations.ConvertContent; + +public class DefaultValuesTests +{ + private readonly Instant now = Instant.FromUtc(2017, 10, 12, 16, 30, 10); + private readonly LanguagesConfig languages = LanguagesConfig.English.Set(Language.DE); + private readonly Schema schema; + + public DefaultValuesTests() + { + schema = + new Schema("my-schema") + .AddString(1, "myString", Partitioning.Language, + new StringFieldProperties { DefaultValue = "en-string", IsRequired = true }) + .AddNumber(2, "myNumber", Partitioning.Invariant, + new NumberFieldProperties()) + .AddDateTime(3, "myDatetime", Partitioning.Invariant, + new DateTimeFieldProperties { DefaultValue = now }) + .AddBoolean(4, "myBoolean", Partitioning.Invariant, + new BooleanFieldProperties { DefaultValue = true, IsRequired = true }) + .AddArray(5, "myArray", Partitioning.Invariant, a => + a.AddString(51, "myArrayString", + new StringFieldProperties { DefaultValue = "array-string" })); + } + + [Fact] + public void Should_enrich_with_default_values() + { + var source = + new ContentData() + .AddField("myString", + new ContentFieldData() + .AddLocalized("de", "de-string")) + .AddField("myNumber", + new ContentFieldData() + .AddInvariant(456)) + .AddField("myArray", + new ContentFieldData() + .AddInvariant( + JsonValue.Array( + JsonValue.Object()))); + + var actual = + new ContentConverter(ResolvedComponents.Empty, schema) + .Add(new AddDefaultValues(languages.ToResolver())) + .Convert(source); + + var expected = + new ContentData() + .AddField("myString", + new ContentFieldData() + .AddLocalized("de", "de-string") + .AddLocalized("en", "en-string")) + .AddField("myNumber", + new ContentFieldData() + .AddInvariant(456)) + .AddField("myDatetime", + new ContentFieldData() + .AddInvariant(now.ToString())) + .AddField("myBoolean", + new ContentFieldData() + .AddInvariant(JsonValue.True)) + .AddField("myArray", + new ContentFieldData() + .AddInvariant( + JsonValue.Array( + JsonValue.Object() + .Add("myArrayString", "array-string")))); + + Assert.Equal(expected, actual); + } + + [Fact] + public void Should_enrich_with_default_values_and_ignore_required_fields() + { + var source = + new ContentData() + .AddField("myNumber", + new ContentFieldData() + .AddInvariant(456)) + .AddField("myArray", + new ContentFieldData() + .AddInvariant( + JsonValue.Array( + JsonValue.Object()))); + + var actual = + new ContentConverter(ResolvedComponents.Empty, schema) + .Add(new AddDefaultValues(languages.ToResolver()) { IgnoreRequiredFields = true }) + .Convert(source); + + var expected = + new ContentData() + .AddField("myNumber", + new ContentFieldData() + .AddInvariant(456)) + .AddField("myDatetime", + new ContentFieldData() + .AddInvariant(now.ToString())) + .AddField("myArray", + new ContentFieldData() + .AddInvariant( + JsonValue.Array( + JsonValue.Object() + .Add("myArrayString", "array-string")))); + + Assert.Equal(expected, actual); + } + + [Fact] + public void Should_enrich_with_default_values_and_ignore_non_master_fields() + { + var source = + new ContentData() + .AddField("myNumber", + new ContentFieldData() + .AddInvariant(456)) + .AddField("myArray", + new ContentFieldData() + .AddInvariant( + JsonValue.Array( + JsonValue.Object()))); + + var actual = + new ContentConverter(ResolvedComponents.Empty, schema) + .Add(new AddDefaultValues(languages.ToResolver()) { IgnoreNonMasterFields = true }) + .Convert(source); + + var expected = + new ContentData() + .AddField("myString", + new ContentFieldData() + .AddLocalized("en", "en-string")) + .AddField("myNumber", + new ContentFieldData() + .AddInvariant(456)) + .AddField("myDatetime", + new ContentFieldData() + .AddInvariant(now.ToString())) + .AddField("myBoolean", + new ContentFieldData() + .AddInvariant(JsonValue.True)) + .AddField("myArray", + new ContentFieldData() + .AddInvariant( + JsonValue.Array( + JsonValue.Object() + .Add("myArrayString", "array-string")))); + + Assert.Equal(expected, actual); + } + + [Fact] + public void Should_not_enrich_with_default_values_if_string_is_empty() + { + var source = + new ContentData() + .AddField("myString", + new ContentFieldData() + .AddLocalized("de", string.Empty)) + .AddField("myNumber", + new ContentFieldData() + .AddInvariant(456)); + + var actual = + new ContentConverter(ResolvedComponents.Empty, schema) + .Add(new AddDefaultValues(languages.ToResolver())) + .Convert(source); + + var expected = + new ContentData() + .AddField("myString", + new ContentFieldData() + .AddLocalized("de", string.Empty) + .AddLocalized("en", "en-string")) + .AddField("myNumber", + new ContentFieldData() + .AddInvariant(456)) + .AddField("myDatetime", + new ContentFieldData() + .AddInvariant(now.ToString())) + .AddField("myBoolean", + new ContentFieldData() + .AddInvariant(JsonValue.True)) + .AddField("myArray", + new ContentFieldData() + .AddInvariant( + JsonValue.Array())); + + Assert.Equal(expected, actual); + } +} diff --git a/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/FieldConvertersTests.cs b/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/FieldConvertersTests.cs index 9f6da35db..8841c02fd 100644 --- a/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/FieldConvertersTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/FieldConvertersTests.cs @@ -212,7 +212,7 @@ public class FieldConvertersTests var actual = new ContentConverter(ResolvedComponents.Empty, schema) - .Add(new ResolveLanguages(languages, true, new[] { Language.DE })) + .Add(new ResolveLanguages(languages, new[] { Language.DE }) { ResolveFallback = true }) .Convert(source); var expected = @@ -248,7 +248,7 @@ public class FieldConvertersTests var actual = new ContentConverter(ResolvedComponents.Empty, schema) - .Add(new ResolveLanguages(languages, false)) + .Add(new ResolveFromPreviousPartitioning(languages)) .Convert(source); var expected = @@ -284,7 +284,7 @@ public class FieldConvertersTests var actual = new ContentConverter(ResolvedComponents.Empty, schema) - .Add(new ResolveLanguages(languages, false, Language.DE)) + .Add(new ResolveLanguages(languages, Language.DE) { ResolveFallback = true }) .Convert(source); var expected = @@ -352,7 +352,7 @@ public class FieldConvertersTests var actual = new ContentConverter(ResolvedComponents.Empty, schema) - .Add(new ResolveLanguages(languages, true, Language.DE)) + .Add(new ResolveLanguages(languages, Language.DE) { ResolveFallback = true }) .Convert(source); var expected = @@ -413,7 +413,7 @@ public class FieldConvertersTests var actual = new ContentConverter(ResolvedComponents.Empty, schema) - .Add(new ResolveInvariant(languages)) + .Add(new ResolveFromPreviousPartitioning(languages)) .Convert(source); var expected = @@ -449,7 +449,7 @@ public class FieldConvertersTests var actual = new ContentConverter(ResolvedComponents.Empty, schema) - .Add(new ResolveInvariant(languages)) + .Add(new ResolveFromPreviousPartitioning(languages)) .Convert(source); var expected = @@ -515,7 +515,7 @@ public class FieldConvertersTests var actual = new ContentConverter(ResolvedComponents.Empty, schema) - .Add(new ResolveLanguages(config)) + .Add(new ResolveLanguages(config) { ResolveFallback = true }) .Convert(source); var expected = @@ -548,7 +548,7 @@ public class FieldConvertersTests var actual = new ContentConverter(ResolvedComponents.Empty, schema) - .Add(new ResolveLanguages(languages, true, Language.IT)) + .Add(new ResolveLanguages(languages, Language.IT) { ResolveFallback = true }) .Convert(source); var expected = @@ -582,7 +582,7 @@ public class FieldConvertersTests var source = new ContentFieldData(); var actual = - new ResolveLanguages(languages, true, Array.Empty()) + new ResolveLanguages(languages, Array.Empty()) { ResolveFallback = true } .ConvertFieldAfter(field, source); Assert.Same(source, actual); @@ -602,7 +602,6 @@ public class FieldConvertersTests Assert.Same(source, actual); } - /* [Fact] public void Should_add_schema_name_to_component() { @@ -616,22 +615,18 @@ public class FieldConvertersTests }); var source = - new ContentFieldData() - .AddInvariant( - new JsonObject() - .Add(Component.Discriminator, componentId)); + JsonValue.Object() + .Add(Component.Discriminator, componentId); var expected = - new ContentFieldData() - .AddInvariant( - new JsonObject() - .Add(Component.Discriminator, componentId) - .Add("schemaName", component.Name)); + JsonValue.Object() + .Add(Component.Discriminator, componentId) + .Add("schemaName", component.Name); - var actual = FieldConverters.AddSchemaName(components)(data, field); - - var expected = new ContentFieldData(); + var actual = + new AddSchemaNames(components) + .ConvertItemBefore(field, source, Enumerable.Empty()); Assert.Equal(expected, actual); - }*/ + } } diff --git a/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/StringFormatterTests.cs b/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/StringFormatterTests.cs index acd397385..15b2be23e 100644 --- a/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/StringFormatterTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/StringFormatterTests.cs @@ -48,7 +48,7 @@ public sealed class StringFormatterTests [Fact] public void Should_format_array_field_with_single_item() { - var value = JsonValue.Array(new JsonObject()); + var value = JsonValue.Array(JsonValue.Object()); var field = Fields.Array(1, "field", Partitioning.Invariant); @@ -60,7 +60,7 @@ public sealed class StringFormatterTests [Fact] public void Should_format_array_field_with_multiple_items() { - var value = JsonValue.Array(new JsonObject(), new JsonObject()); + var value = JsonValue.Array(JsonValue.Object(), JsonValue.Object()); var field = Fields.Array(1, "field", Partitioning.Invariant); @@ -96,7 +96,7 @@ public sealed class StringFormatterTests [Fact] public void Should_format_assets_field_with_single_item() { - var value = JsonValue.Array(new JsonObject()); + var value = JsonValue.Array(JsonValue.Object()); var field = Fields.Assets(1, "field", Partitioning.Invariant); @@ -108,7 +108,7 @@ public sealed class StringFormatterTests [Fact] public void Should_format_assets_field_with_multiple_items() { - var value = JsonValue.Array(new JsonObject(), new JsonObject()); + var value = JsonValue.Array(JsonValue.Object(), JsonValue.Object()); var field = Fields.Assets(1, "field", Partitioning.Invariant); @@ -168,7 +168,7 @@ public sealed class StringFormatterTests [Fact] public void Should_format_component_field() { - var value = new JsonObject(); + var value = JsonValue.Object(); var field = Fields.Component(1, "field", Partitioning.Invariant); @@ -192,7 +192,7 @@ public sealed class StringFormatterTests [Fact] public void Should_format_components_field_with_single_item() { - var value = JsonValue.Array(new JsonObject()); + var value = JsonValue.Array(JsonValue.Object()); var field = Fields.Components(1, "field", Partitioning.Invariant); @@ -204,7 +204,7 @@ public sealed class StringFormatterTests [Fact] public void Should_format_components_field_with_multiple_items() { - var value = JsonValue.Array(new JsonObject(), new JsonObject()); + var value = JsonValue.Array(JsonValue.Object(), JsonValue.Object()); var field = Fields.Components(1, "field", Partitioning.Invariant); @@ -228,7 +228,7 @@ public sealed class StringFormatterTests [Fact] public void Should_format_geolocation_field_with_correct_data() { - var value = new JsonObject().Add("latitude", 18.9).Add("longitude", 10.9); + var value = JsonValue.Object().Add("latitude", 18.9).Add("longitude", 10.9); var field = Fields.Geolocation(1, "field", Partitioning.Invariant); @@ -240,7 +240,7 @@ public sealed class StringFormatterTests [Fact] public void Should_format_geolocation_field_with_missing_property() { - var value = new JsonObject().Add("latitude", 18.9); + var value = JsonValue.Object().Add("latitude", 18.9); var field = Fields.Geolocation(1, "field", Partitioning.Invariant); @@ -264,7 +264,7 @@ public sealed class StringFormatterTests [Fact] public void Should_format_json_field() { - var value = new JsonObject(); + var value = JsonValue.Object(); var field = Fields.Json(1, "field", Partitioning.Invariant); @@ -300,7 +300,7 @@ public sealed class StringFormatterTests [Fact] public void Should_format_references_field_with_single_item() { - var value = JsonValue.Array(new JsonObject()); + var value = JsonValue.Array(JsonValue.Object()); var field = Fields.References(1, "field", Partitioning.Invariant); @@ -312,7 +312,7 @@ public sealed class StringFormatterTests [Fact] public void Should_format_references_field_with_multiple_items() { - var value = JsonValue.Array(new JsonObject(), new JsonObject()); + var value = JsonValue.Array(JsonValue.Object(), JsonValue.Object()); var field = Fields.References(1, "field", Partitioning.Invariant); diff --git a/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/ValueConvertersTests.cs b/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/ValueConvertersTests.cs index 71d80dd89..00538b9ce 100644 --- a/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/ValueConvertersTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/ValueConvertersTests.cs @@ -162,15 +162,15 @@ public class ValueConvertersTests }); var source = - new JsonObject() + JsonValue.Object() .Add(Component.Discriminator, componentId); var actual = new AddSchemaNames(components) - .ConvertItem(field, source); + .ConvertItemBefore(field, source, Enumerable.Empty()); var expected = - new JsonObject() + JsonValue.Object() .Add(Component.Discriminator, componentId) .Add("schemaName", component.Name); @@ -190,13 +190,13 @@ public class ValueConvertersTests }); var source = - new JsonObject() + JsonValue.Object() .Add(Component.Discriminator, componentId) .Add("schemaName", "existing"); var actual = new AddSchemaNames(components) - .ConvertItem(field, source); + .ConvertItemBefore(field, source, Enumerable.Empty()); var expected = source; @@ -216,12 +216,12 @@ public class ValueConvertersTests }); var source = - new JsonObject() + JsonValue.Object() .Add(Component.Discriminator, componentId); var actual = new AddSchemaNames(components) - .ConvertItem(field, source); + .ConvertItemBefore(field, source, Enumerable.Empty()); var expected = source; @@ -241,11 +241,11 @@ public class ValueConvertersTests }); var source = - new JsonObject(); + JsonValue.Object(); var actual = new AddSchemaNames(components) - .ConvertItem(field, source); + .ConvertItemBefore(field, source, Enumerable.Empty()); var expected = source; @@ -260,12 +260,12 @@ public class ValueConvertersTests var componentId = DomainId.NewGuid(); var source = - new JsonObject() + JsonValue.Object() .Add(Component.Discriminator, componentId); var actual = new AddSchemaNames(ResolvedComponents.Empty) - .ConvertItem(field, source); + .ConvertItemBefore(field, source, Enumerable.Empty()); var expected = source; diff --git a/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ExtractReferenceIds/ReferenceExtractionTests.cs b/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ExtractReferenceIds/ReferenceExtractionTests.cs index ed61740df..48e33111a 100644 --- a/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ExtractReferenceIds/ReferenceExtractionTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ExtractReferenceIds/ReferenceExtractionTests.cs @@ -95,44 +95,44 @@ public class ReferenceExtractionTests new ContentFieldData() .AddInvariant( JsonValue.Array( - new JsonObject() + JsonValue.Object() .Add("nestedAssets", JsonValue.Array(id1, id2)) .Add("nestedComponent", - new JsonObject() + JsonValue.Object() .Add("references", JsonValue.Array(id1, id2)) .Add(Component.Discriminator, DomainId.Empty)) .Add("nestedComponents", JsonValue.Array( - new JsonObject() + JsonValue.Object() .Add("references", JsonValue.Array(id1, id2)) .Add(Component.Discriminator, DomainId.Empty)))))) .AddField("component", new ContentFieldData() .AddInvariant( - new JsonObject() + JsonValue.Object() .Add("references", JsonValue.Array(id1, id2)) .Add("assets1", JsonValue.Array(id1)) .Add("array", JsonValue.Array( - new JsonObject() + JsonValue.Object() .Add("nestedAssets", JsonValue.Array(id1, id2)))) .Add(Component.Discriminator, DomainId.Empty))) .AddField("components", new ContentFieldData() .AddInvariant( JsonValue.Array( - new JsonObject() + JsonValue.Object() .Add("references", JsonValue.Array(id1, id2)) .Add("assets1", JsonValue.Array(id1)) .Add("array", JsonValue.Array( - new JsonObject() + JsonValue.Object() .Add("nestedAssets", JsonValue.Array(id1, id2)))) .Add(Component.Discriminator, DomainId.Empty)))); @@ -148,44 +148,44 @@ public class ReferenceExtractionTests new ContentFieldData() .AddInvariant( JsonValue.Array( - new JsonObject() + JsonValue.Object() .Add("nestedAssets", JsonValue.Array(id2)) .Add("nestedComponent", - new JsonObject() + JsonValue.Object() .Add("references", JsonValue.Array(id2)) .Add(Component.Discriminator, DomainId.Empty)) .Add("nestedComponents", JsonValue.Array( - new JsonObject() + JsonValue.Object() .Add("references", JsonValue.Array(id2)) .Add(Component.Discriminator, DomainId.Empty)))))) .AddField("component", new ContentFieldData() .AddInvariant( - new JsonObject() + JsonValue.Object() .Add("references", JsonValue.Array(id2)) .Add("assets1", new JsonArray()) .Add("array", JsonValue.Array( - new JsonObject() + JsonValue.Object() .Add("nestedAssets", JsonValue.Array(id2)))) .Add(Component.Discriminator, DomainId.Empty))) .AddField("components", new ContentFieldData() .AddInvariant( JsonValue.Array( - new JsonObject() + JsonValue.Object() .Add("references", JsonValue.Array(id2)) .Add("assets1", new JsonArray()) .Add("array", JsonValue.Array( - new JsonObject() + JsonValue.Object() .Add("nestedAssets", JsonValue.Array(id2)))) .Add(Component.Discriminator, DomainId.Empty)))); @@ -218,7 +218,7 @@ public class ReferenceExtractionTests var value = JsonValue.Array( - new JsonObject() + JsonValue.Object() .Add(field.Name, CreateValue(id1, id2))); var actual = arrayField.GetReferencedIds(value, components).ToArray(); diff --git a/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ExtractReferenceIds/ReferenceFormattingTests.cs b/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ExtractReferenceIds/ReferenceFormattingTests.cs index 1bd76abf1..8d73a3f21 100644 --- a/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ExtractReferenceIds/ReferenceFormattingTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ExtractReferenceIds/ReferenceFormattingTests.cs @@ -35,7 +35,7 @@ public class ReferenceFormattingTests var formatted = data.FormatReferences(schema, languages); var expected = - new JsonObject() + JsonValue.Object() .Add("en", "EN, 12") .Add("de", "DE, 12"); @@ -52,7 +52,7 @@ public class ReferenceFormattingTests var formatted = data.FormatReferences(schema, languages); var expected = - new JsonObject() + JsonValue.Object() .Add("en", "EN") .Add("de", "DE"); @@ -69,7 +69,7 @@ public class ReferenceFormattingTests var formatted = data.FormatReferences(schema, languages); var expected = - new JsonObject() + JsonValue.Object() .Add("en", string.Empty) .Add("de", string.Empty); diff --git a/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/HandleRules/RuleEventFormatterCompareTests.cs b/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/HandleRules/RuleEventFormatterCompareTests.cs index cc1eab8ce..6a3bf5156 100644 --- a/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/HandleRules/RuleEventFormatterCompareTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/HandleRules/RuleEventFormatterCompareTests.cs @@ -599,7 +599,7 @@ public class RuleEventFormatterCompareTests new ContentData() .AddField("city", new ContentFieldData() - .AddInvariant(new JsonObject().Add("name", "Berlin"))) + .AddInvariant(JsonValue.Object().Add("name", "Berlin"))) }; var actual = await sut.FormatAsync(script, @event); @@ -671,7 +671,7 @@ public class RuleEventFormatterCompareTests new ContentData() .AddField("city", new ContentFieldData() - .AddInvariant(new JsonObject().Add("name", "Berlin"))) + .AddInvariant(JsonValue.Object().Add("name", "Berlin"))) }; var actual = await sut.FormatAsync(script, @event); @@ -695,7 +695,7 @@ public class RuleEventFormatterCompareTests new ContentData() .AddField("city", new ContentFieldData() - .AddInvariant(new JsonObject().Add("name", "Berlin"))) + .AddInvariant(JsonValue.Object().Add("name", "Berlin"))) }; var actual = await sut.FormatAsync(script, @event); @@ -743,7 +743,7 @@ public class RuleEventFormatterCompareTests new ContentData() .AddField("city", new ContentFieldData() - .AddInvariant(new JsonObject().Add("name", "Berlin"))) + .AddInvariant(JsonValue.Object().Add("name", "Berlin"))) }; var actual = await sut.FormatAsync(script, @event); diff --git a/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/Scripting/ContentDataObjectTests.cs b/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/Scripting/ContentDataObjectTests.cs index 97649965d..be3bfe887 100644 --- a/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/Scripting/ContentDataObjectTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/Scripting/ContentDataObjectTests.cs @@ -210,13 +210,13 @@ public class ContentDataObjectTests new ContentData() .AddField("geo", new ContentFieldData() - .AddInvariant(new JsonObject().Add("lat", 1.0))); + .AddInvariant(JsonValue.Object().Add("lat", 1.0))); var expected = new ContentData() .AddField("geo", new ContentFieldData() - .AddInvariant(new JsonObject().Add("lat", 1.0).Add("lon", 4.0))); + .AddInvariant(JsonValue.Object().Add("lat", 1.0).Add("lon", 4.0))); const string script = @" data.geo.iv = { lat: data.geo.iv.lat, lon: data.geo.iv.lat + 3 } @@ -234,13 +234,13 @@ public class ContentDataObjectTests new ContentData() .AddField("geo", new ContentFieldData() - .AddInvariant(new JsonObject().Add("lat", 1.0))); + .AddInvariant(JsonValue.Object().Add("lat", 1.0))); var expected = new ContentData() .AddField("geo", new ContentFieldData() - .AddInvariant(new JsonObject().Add("lat", 2.0).Add("lon", 4.0))); + .AddInvariant(JsonValue.Object().Add("lat", 2.0).Add("lon", 4.0))); const string script = @" var nested = data.geo.iv; @@ -261,7 +261,7 @@ public class ContentDataObjectTests new ContentData() .AddField("geo", new ContentFieldData() - .AddInvariant(new JsonObject().Add("lat", 2.0).Add("lon", 4.0))); + .AddInvariant(JsonValue.Object().Add("lat", 2.0).Add("lon", 4.0))); const string script = @" var nested = data.geo.iv; diff --git a/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/Scripting/JintScriptEngineHelperTests.cs b/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/Scripting/JintScriptEngineHelperTests.cs index 9725103a6..8994dff4f 100644 --- a/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/Scripting/JintScriptEngineHelperTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/Scripting/JintScriptEngineHelperTests.cs @@ -404,7 +404,7 @@ public class JintScriptEngineHelperTests : IClassFixture httpHandler.ShouldBeMethod(HttpMethod.Get); httpHandler.ShouldBeUrl("http://squidex.io/"); - var expectedResult = new JsonObject().Add("key", 42); + var expectedResult = JsonValue.Object().Add("key", 42); Assert.Equal(expectedResult, actual); } @@ -438,7 +438,7 @@ public class JintScriptEngineHelperTests : IClassFixture httpHandler.ShouldBeHeader("X-Header1", "1"); httpHandler.ShouldBeHeader("X-Header2", "2"); - var expectedResult = new JsonObject().Add("key", 42); + var expectedResult = JsonValue.Object().Add("key", 42); Assert.Equal(expectedResult, actual); } @@ -465,7 +465,7 @@ public class JintScriptEngineHelperTests : IClassFixture httpHandler.ShouldBeMethod(HttpMethod.Delete); httpHandler.ShouldBeUrl("http://squidex.io/"); - var expectedResult = new JsonObject().Add("key", 42); + var expectedResult = JsonValue.Object().Add("key", 42); Assert.Equal(expectedResult, actual); } @@ -495,7 +495,7 @@ public class JintScriptEngineHelperTests : IClassFixture httpHandler.ShouldBeUrl("http://squidex.io/"); httpHandler.ShouldBeBody("{\"key\":42}", "text/json"); - var expectedResult = new JsonObject().Add("key", 42); + var expectedResult = JsonValue.Object().Add("key", 42); Assert.Equal(expectedResult, actual); } @@ -525,7 +525,7 @@ public class JintScriptEngineHelperTests : IClassFixture httpHandler.ShouldBeUrl("http://squidex.io/"); httpHandler.ShouldBeBody("{\"key\":42}", "text/json"); - var expectedResult = new JsonObject().Add("key", 42); + var expectedResult = JsonValue.Object().Add("key", 42); Assert.Equal(expectedResult, actual); } @@ -555,7 +555,7 @@ public class JintScriptEngineHelperTests : IClassFixture httpHandler.ShouldBeUrl("http://squidex.io/"); httpHandler.ShouldBeBody("{\"key\":42}", "text/json"); - var expectedResult = new JsonObject().Add("key", 42); + var expectedResult = JsonValue.Object().Add("key", 42); Assert.Equal(expectedResult, actual); } diff --git a/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/ArrayFieldTests.cs b/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/ArrayFieldTests.cs index f6f1d0c13..44d3486cf 100644 --- a/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/ArrayFieldTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/ArrayFieldTests.cs @@ -137,12 +137,12 @@ public class ArrayFieldTests : IClassFixture private static JsonObject Object() { - return new JsonObject(); + return JsonValue.Object(); } private static JsonObject Object(string key, JsonValue value) { - return new JsonObject().Add(key, value); + return JsonValue.Object().Add(key, value); } private static RootField Field(ArrayFieldProperties properties) diff --git a/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/ComponentFieldTests.cs b/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/ComponentFieldTests.cs index 56061a968..a9e6ad051 100644 --- a/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/ComponentFieldTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/ComponentFieldTests.cs @@ -142,7 +142,7 @@ public class ComponentFieldTests : IClassFixture private static JsonValue CreateValue(string? type, string key, JsonValue value, string? discriminator = null) { - var obj = new JsonObject(); + var obj = JsonValue.Object(); if (type != null) { diff --git a/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/ComponentsFieldTests.cs b/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/ComponentsFieldTests.cs index 88c19ee9c..a0ad917e5 100644 --- a/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/ComponentsFieldTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/ComponentsFieldTests.cs @@ -200,7 +200,7 @@ public class ComponentsFieldTests : IClassFixture for (var i = 0; i < count; i++) { - var obj = new JsonObject(); + var obj = JsonValue.Object(); if (type != null) { diff --git a/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/ContentValidationTests.cs b/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/ContentValidationTests.cs index 677741d27..41194f9db 100644 --- a/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/ContentValidationTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/ContentValidationTests.cs @@ -408,9 +408,9 @@ public class ContentValidationTests : IClassFixture new ContentFieldData() .AddInvariant( JsonValue.Array( - new JsonObject(), - new JsonObject().Add("myNested", 1), - new JsonObject()))); + JsonValue.Object(), + JsonValue.Object().Add("myNested", 1), + JsonValue.Object()))); await data.ValidatePartialAsync(languages.ToResolver(), errors, schema); @@ -447,7 +447,7 @@ public class ContentValidationTests : IClassFixture new ContentFieldData() .AddInvariant( JsonValue.Array( - new JsonObject()))); + JsonValue.Object()))); await data.ValidateAsync(languages.ToResolver(), errors, schema); diff --git a/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/GeolocationFieldTests.cs b/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/GeolocationFieldTests.cs index 298e4f9da..45ac0b663 100644 --- a/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/GeolocationFieldTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/GeolocationFieldTests.cs @@ -38,7 +38,7 @@ public class GeolocationFieldTests : IClassFixture { var sut = Field(new GeolocationFieldProperties()); - var geolocation = new JsonObject() + var geolocation = JsonValue.Object() .Add("coordinates", JsonValue.Array( JsonValue.Create(12), @@ -96,7 +96,7 @@ public class GeolocationFieldTests : IClassFixture private static JsonValue CreateValue(double lat, double lon) { - return new JsonObject().Add("latitude", lat).Add("longitude", lon); + return JsonValue.Object().Add("latitude", lat).Add("longitude", lon); } private static RootField Field(GeolocationFieldProperties properties) diff --git a/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/UIFieldTests.cs b/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/UIFieldTests.cs index cd9a83b4b..1c46e9cfb 100644 --- a/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/UIFieldTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/UIFieldTests.cs @@ -97,7 +97,7 @@ public class UIFieldTests : IClassFixture .AddField("myArray", new ContentFieldData() .AddInvariant( JsonValue.Array( - new JsonObject() + JsonValue.Object() .Add("myUI", default)))); var dataErrors = new List(); diff --git a/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/Validators/ComponentValidatorTests.cs b/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/Validators/ComponentValidatorTests.cs index a18e500f0..5eb073180 100644 --- a/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/Validators/ComponentValidatorTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/Validators/ComponentValidatorTests.cs @@ -23,7 +23,7 @@ public class ComponentValidatorTests : IClassFixture { var validator = A.Fake(); - var componentData = new JsonObject(); + var componentData = JsonValue.Object(); var componentObject = new Component("type", componentData, new Schema("my-schema")); var isFactoryCalled = false; diff --git a/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/Validators/UniqueObjectValuesValidatorTests.cs b/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/Validators/UniqueObjectValuesValidatorTests.cs index a3a05035e..95db62b47 100644 --- a/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/Validators/UniqueObjectValuesValidatorTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/Validators/UniqueObjectValuesValidatorTests.cs @@ -42,9 +42,9 @@ public class UniqueObjectValuesValidatorTests : IClassFixture [Fact] public async Task UpdateRole_should_create_events_and_update_role() { - var command = new UpdateRole { Name = roleName, Permissions = new[] { "clients.read" }, Properties = new JsonObject() }; + var command = new UpdateRole { Name = roleName, Permissions = new[] { "clients.read" }, Properties = JsonValue.Object() }; await ExecuteCreateAsync(); await ExecuteAddRoleAsync(); diff --git a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Assets/Queries/AssetQueryServiceTests.cs b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Assets/Queries/AssetQueryServiceTests.cs index fd03cfd2f..e65801e82 100644 --- a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Assets/Queries/AssetQueryServiceTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Assets/Queries/AssetQueryServiceTests.cs @@ -206,21 +206,6 @@ public class AssetQueryServiceTests : GivenContext Assert.Same(assetFolders, actual); } - [Fact] - public async Task Should_query_asset_folders_with_appId() - { - var parentId = DomainId.NewGuid(); - - var assetFolders = ResultList.CreateFrom(10); - - A.CallTo(() => assetFolderRepository.QueryAsync(AppId.Id, parentId, A._)) - .Returns(assetFolders); - - var actual = await sut.QueryAssetFoldersAsync(AppId.Id, parentId, CancellationToken); - - Assert.Same(assetFolders, actual); - } - [Fact] public async Task Should_find_asset_folder_with_path() { diff --git a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/BackupContentsTests.cs b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/BackupContentsTests.cs index 19b5233b7..2b470be1b 100644 --- a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/BackupContentsTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/BackupContentsTests.cs @@ -107,7 +107,7 @@ public class BackupContentsTests : GivenContext .AddField("assetsInObj", new ContentFieldData() .AddLocalized("iv", - new JsonObject() + JsonValue.Object() .Add("asset", $"Asset: {oldAssetsUrlApp}/my-asset.jpg."))); var updateData = @@ -124,7 +124,7 @@ public class BackupContentsTests : GivenContext .AddField("assetsInObj", new ContentFieldData() .AddLocalized("iv", - new JsonObject() + JsonValue.Object() .Add("asset", $"Asset: {newAssetsUrlApp}/my-asset.jpg."))); var context = new RestoreContext(AppId.Id, new UserMapping(me), reader, DomainId.NewGuid()); diff --git a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/TestContent.cs b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/TestContent.cs index 853e57ff8..c924b5503 100644 --- a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/TestContent.cs +++ b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/TestContent.cs @@ -236,29 +236,29 @@ public static class TestContent .AddField("my-geolocation", new ContentFieldData() .AddInvariant( - new JsonObject() + JsonValue.Object() .Add("latitude", 10) .Add("longitude", 20))) .AddField("my-component", new ContentFieldData() .AddInvariant( - new JsonObject() + JsonValue.Object() .Add(Component.Discriminator, TestSchemas.Ref1.Id) .Add("schemaRef1Field", "Component1"))) .AddField("my-components", new ContentFieldData() .AddInvariant( JsonValue.Array( - new JsonObject() + JsonValue.Object() .Add(Component.Discriminator, TestSchemas.Ref1.Id) .Add("schemaRef1Field", "Component1"), - new JsonObject() + JsonValue.Object() .Add(Component.Discriminator, TestSchemas.Ref2.Id) .Add("schemaRef2Field", "Component2")))) .AddField("my-json", new ContentFieldData() .AddInvariant( - new JsonObject() + JsonValue.Object() .Add("value", 1))) .AddField("my-json2", new ContentFieldData() @@ -287,10 +287,10 @@ public static class TestContent .AddField("my-array", new ContentFieldData() .AddInvariant(JsonValue.Array( - new JsonObject() + JsonValue.Object() .Add("nested-number", 42) .Add("nested-boolean", true), - new JsonObject() + JsonValue.Object() .Add("nested-number", 3.14) .Add("nested-boolean", false)))); diff --git a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/Queries/ConvertDataTests.cs b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/Queries/ConvertDataTests.cs index f9fa9254f..124acbd45 100644 --- a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/Queries/ConvertDataTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/Queries/ConvertDataTests.cs @@ -14,6 +14,7 @@ using Squidex.Domain.Apps.Entities.Contents.Queries.Steps; using Squidex.Domain.Apps.Entities.Contents.Repositories; using Squidex.Domain.Apps.Entities.TestHelpers; using Squidex.Infrastructure; +using Squidex.Infrastructure.Collections; using Squidex.Infrastructure.Json.Objects; using TestUtils = Squidex.Domain.Apps.Core.TestHelpers.TestUtils; @@ -30,10 +31,13 @@ public class ConvertDataTests : GivenContext { var schemaDef = new Schema(SchemaId.Name) - .AddReferences(1, "references", Partitioning.Invariant) - .AddAssets(2, "assets", Partitioning.Invariant) + .AddReferences(1, "references", Partitioning.Invariant, + new ReferencesFieldProperties { DefaultValue = ReadonlyList.Create("default1") }) + .AddAssets(2, "assets", Partitioning.Invariant, + new AssetsFieldProperties { DefaultValue = ReadonlyList.Create("default2") }) .AddArray(3, "array", Partitioning.Invariant, a => a - .AddAssets(31, "nested")); + .AddAssets(31, "nested", + new AssetsFieldProperties { DefaultValue = ReadonlyList.Create("default3") })); A.CallTo(() => Schema.SchemaDef) .Returns(schemaDef); @@ -51,6 +55,39 @@ public class ConvertDataTests : GivenContext Assert.NotNull(content.Data); } + [Fact] + public async Task Should_enrich_with_default_value() + { + var source = + new ContentData() + .AddField("array", + new ContentFieldData() + .AddInvariant( + JsonValue.Array( + JsonValue.Object()))); + + var content = CreateContent(source); + + var expected = + new ContentData() + .AddField("references", + new ContentFieldData() + .AddInvariant(JsonValue.Array("default1"))) + .AddField("assets", + new ContentFieldData() + .AddInvariant(JsonValue.Array("default2"))) + .AddField("array", + new ContentFieldData() + .AddInvariant( + JsonValue.Array( + JsonValue.Object() + .Add("nested", JsonValue.Array("default3"))))); + + await sut.EnrichAsync(ApiContext, new[] { content }, SchemaProvider(), CancellationToken); + + Assert.Equal(expected, content.Data); + } + [Fact] public async Task Should_cleanup_references() { @@ -73,7 +110,7 @@ public class ConvertDataTests : GivenContext new ContentFieldData() .AddInvariant( JsonValue.Array( - new JsonObject() + JsonValue.Object() .Add("nested", JsonValue.Array(id2))))); A.CallTo(() => assetRepository.QueryIdsAsync(AppId.Id, A>.That.Is(id1, id2), CancellationToken)) @@ -109,7 +146,7 @@ public class ConvertDataTests : GivenContext new ContentFieldData() .AddInvariant( JsonValue.Array( - new JsonObject() + JsonValue.Object() .Add("nested", JsonValue.Array())))); A.CallTo(() => assetRepository.QueryIdsAsync(AppId.Id, A>.That.Is(id1, id2), CancellationToken)) @@ -136,7 +173,7 @@ public class ConvertDataTests : GivenContext new ContentFieldData() .AddInvariant( JsonValue.Array( - new JsonObject() + JsonValue.Object() .Add("nested", JsonValue.Array(id1, id2))))); } diff --git a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/Queries/ResolveReferencesTests.cs b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/Queries/ResolveReferencesTests.cs index 5d6ece2e2..b235ec3ad 100644 --- a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/Queries/ResolveReferencesTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/Queries/ResolveReferencesTests.cs @@ -144,13 +144,13 @@ public class ResolveReferencesTests : GivenContext, IClassFixture>(value); diff --git a/frontend/src/app/shared/services/auth.service.ts b/frontend/src/app/shared/services/auth.service.ts index 29790836f..6a27789e8 100644 --- a/frontend/src/app/shared/services/auth.service.ts +++ b/frontend/src/app/shared/services/auth.service.ts @@ -6,7 +6,7 @@ */ import { Injectable } from '@angular/core'; -import { Log, User, UserManager } from 'oidc-client-ts'; +import { Log, User, UserManager, WebStorageStateStore } from 'oidc-client-ts'; import { Observable, ReplaySubject } from 'rxjs'; import { ApiUrlConfig } from '@app/framework'; @@ -103,6 +103,7 @@ export class AuthService { silent_redirect_uri: apiUrl.buildUrl('client-callback-silent.html'), popup_redirect_uri: apiUrl.buildUrl('client-callback-popup.html'), authority: apiUrl.buildUrl('identity-server/'), + userStore: new WebStorageStateStore({ store: window.localStorage || window.sessionStorage }), }); this.userManager.events.addUserLoaded(user => { diff --git a/tools/TestSuite/TestSuite.ApiTests/AssetFoldersTests.cs b/tools/TestSuite/TestSuite.ApiTests/AssetFoldersTests.cs new file mode 100644 index 000000000..219b11abd --- /dev/null +++ b/tools/TestSuite/TestSuite.ApiTests/AssetFoldersTests.cs @@ -0,0 +1,129 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using Squidex.ClientLibrary.Management; +using TestSuite.Fixtures; + +#pragma warning disable SA1300 // Element should begin with upper-case letter +#pragma warning disable SA1507 // Code should not contain multiple blank lines in a row + +namespace TestSuite.ApiTests; + +[UsesVerify] +public class AssetFoldersTests : IClassFixture +{ + public CreatedAppFixture _ { get; } + + public AssetFoldersTests(CreatedAppFixture fixture) + { + _ = fixture; + } + + [Fact] + public async Task Should_create_folder() + { + // STEP 1: Create folder. + var createRequest = new CreateAssetFolderDto + { + FolderName = Guid.NewGuid().ToString() + }; + + var folder = await _.Client.Assets.PostAssetFolderAsync(createRequest); + + Assert.Equal(createRequest.FolderName, folder.FolderName); + + await Verify(folder); + } + + [Fact] + public async Task Should_update_folder() + { + // STEP 1: Create folder. + var createRequest = new CreateAssetFolderDto + { + FolderName = Guid.NewGuid().ToString() + }; + + var folder_0 = await _.Client.Assets.PostAssetFolderAsync(createRequest); + + + // STEP 2: Update folder + var updateRequest = new RenameAssetFolderDto + { + FolderName = Guid.NewGuid().ToString() + }; + + var folder_1 = await _.Client.Assets.PutAssetFolderAsync(folder_0.Id, updateRequest); + + Assert.Equal(updateRequest.FolderName, folder_1.FolderName); + + await Verify(folder_1); + } + + [Fact] + public async Task Should_delete_folder() + { + // STEP 1: Create folder. + var createRequest = new CreateAssetFolderDto + { + FolderName = Guid.NewGuid().ToString() + }; + + var folder_0 = await _.Client.Assets.PostAssetFolderAsync(createRequest); + + + // STEP 2: Update folder + await _.Client.Assets.DeleteAssetFolderAsync(folder_0.Id); + + // Should not return deleted folder. + var folders = await _.Client.Assets.GetAssetFoldersAsync(folder_0.Id); + + Assert.DoesNotContain(folders.Items, x => x.Id == folder_0.Id); + } + + [Fact] + public async Task Should_create_and_query_nested_folders() + { + // STEP 1: Create folder. + var createRequest = new CreateAssetFolderDto + { + FolderName = Guid.NewGuid().ToString() + }; + + var folder1 = await _.Client.Assets.PostAssetFolderAsync(createRequest); + + + // STEP 2: Create nested folder. + var createRequest2 = new CreateAssetFolderDto + { + FolderName = Guid.NewGuid().ToString(), + // Create a nested asset folder. + ParentId = folder1.Id + }; + + var folder2 = await _.Client.Assets.PostAssetFolderAsync(createRequest2); + + + // STEP 3: Query by root id. + var folders1 = await _.Client.Assets.GetAssetFoldersAsync(folder1.ParentId); + + Assert.Contains(folder1.Id, folders1.Items.Select(x => x.Id)); + + + // STEP 3: Query by nested id. + var folders2 = await _.Client.Assets.GetAssetFoldersAsync(folder1.Id); + + Assert.Equal(new[] { folder2.Id }, folders2.Items.Select(x => x.Id)); + + + // STEP 3: Query all + var folders3 = await _.Client.Assets.GetAssetFoldersAsync(); + + Assert.Contains(folder1.Id, folders3.Items.Select(x => x.Id)); + Assert.Contains(folder2.Id, folders3.Items.Select(x => x.Id)); + } +} diff --git a/tools/TestSuite/TestSuite.ApiTests/GraphQLSubscriptionTests.cs b/tools/TestSuite/TestSuite.ApiTests/GraphQLSubscriptionTests.cs index 95442e197..a4936db11 100644 --- a/tools/TestSuite/TestSuite.ApiTests/GraphQLSubscriptionTests.cs +++ b/tools/TestSuite/TestSuite.ApiTests/GraphQLSubscriptionTests.cs @@ -5,7 +5,6 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== -using System; using System.Reactive.Linq; using GraphQL; using GraphQL.Client.Http; diff --git a/tools/TestSuite/TestSuite.ApiTests/TestSuite.ApiTests.csproj b/tools/TestSuite/TestSuite.ApiTests/TestSuite.ApiTests.csproj index 64a55ddd8..81e425730 100644 --- a/tools/TestSuite/TestSuite.ApiTests/TestSuite.ApiTests.csproj +++ b/tools/TestSuite/TestSuite.ApiTests/TestSuite.ApiTests.csproj @@ -24,7 +24,7 @@ - + diff --git a/tools/TestSuite/TestSuite.ApiTests/Verify/AssetFoldersTests.Should_create_folder.verified.txt b/tools/TestSuite/TestSuite.ApiTests/Verify/AssetFoldersTests.Should_create_folder.verified.txt new file mode 100644 index 000000000..8bfb269a5 --- /dev/null +++ b/tools/TestSuite/TestSuite.ApiTests/Verify/AssetFoldersTests.Should_create_folder.verified.txt @@ -0,0 +1,16 @@ +{ + Id: Guid_1, + ParentId: Guid_Empty, + FolderName: Guid_2, + _links: { + delete: { + Method: DELETE + }, + move: { + Method: PUT + }, + update: { + Method: PUT + } + } +} \ No newline at end of file diff --git a/tools/TestSuite/TestSuite.ApiTests/Verify/AssetFoldersTests.Should_update_folder.verified.txt b/tools/TestSuite/TestSuite.ApiTests/Verify/AssetFoldersTests.Should_update_folder.verified.txt new file mode 100644 index 000000000..d5f3d47cc --- /dev/null +++ b/tools/TestSuite/TestSuite.ApiTests/Verify/AssetFoldersTests.Should_update_folder.verified.txt @@ -0,0 +1,17 @@ +{ + Id: Guid_1, + ParentId: Guid_Empty, + FolderName: Guid_2, + Version: 1, + _links: { + delete: { + Method: DELETE + }, + move: { + Method: PUT + }, + update: { + Method: PUT + } + } +} \ No newline at end of file diff --git a/tools/TestSuite/TestSuite.ApiTests/Verify/ContentUpdateTests.Should_create_json_with_dot.verified.txt b/tools/TestSuite/TestSuite.ApiTests/Verify/ContentUpdateTests.Should_create_json_with_dot.verified.txt index bf0fdc030..a9524dabb 100644 --- a/tools/TestSuite/TestSuite.ApiTests/Verify/ContentUpdateTests.Should_create_json_with_dot.verified.txt +++ b/tools/TestSuite/TestSuite.ApiTests/Verify/ContentUpdateTests.Should_create_json_with_dot.verified.txt @@ -1,5 +1,10 @@ { Data: { + Localized: { + custom: default, + de: default, + en: default + }, Json: { field.with.dot: [] } diff --git a/tools/TestSuite/TestSuite.ApiTests/Verify/ContentUpdateTests.Should_create_non_published_content.verified.txt b/tools/TestSuite/TestSuite.ApiTests/Verify/ContentUpdateTests.Should_create_non_published_content.verified.txt index f1138301d..5c4a2bfeb 100644 --- a/tools/TestSuite/TestSuite.ApiTests/Verify/ContentUpdateTests.Should_create_non_published_content.verified.txt +++ b/tools/TestSuite/TestSuite.ApiTests/Verify/ContentUpdateTests.Should_create_non_published_content.verified.txt @@ -1,5 +1,10 @@ { Data: { + Localized: { + custom: default, + de: default, + en: default + }, Number: 1 }, NewStatus: , diff --git a/tools/TestSuite/TestSuite.ApiTests/Verify/ContentUpdateTests.Should_create_published_content.verified.txt b/tools/TestSuite/TestSuite.ApiTests/Verify/ContentUpdateTests.Should_create_published_content.verified.txt index 3e206dfe2..db7e237fb 100644 --- a/tools/TestSuite/TestSuite.ApiTests/Verify/ContentUpdateTests.Should_create_published_content.verified.txt +++ b/tools/TestSuite/TestSuite.ApiTests/Verify/ContentUpdateTests.Should_create_published_content.verified.txt @@ -1,5 +1,10 @@ { Data: { + Localized: { + custom: default, + de: default, + en: default + }, Number: 1 }, NewStatus: , diff --git a/tools/TestSuite/TestSuite.ApiTests/Verify/ContentUpdateTests.Should_create_strange_text.verified.txt b/tools/TestSuite/TestSuite.ApiTests/Verify/ContentUpdateTests.Should_create_strange_text.verified.txt index 49a457c5d..166ae96d1 100644 --- a/tools/TestSuite/TestSuite.ApiTests/Verify/ContentUpdateTests.Should_create_strange_text.verified.txt +++ b/tools/TestSuite/TestSuite.ApiTests/Verify/ContentUpdateTests.Should_create_strange_text.verified.txt @@ -1,5 +1,10 @@ { Data: { + Localized: { + custom: default, + de: default, + en: default + }, String: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36 }, NewStatus: , diff --git a/tools/TestSuite/TestSuite.ApiTests/Verify/ContentUpdateTests.Should_get_content_by_version.verified.txt b/tools/TestSuite/TestSuite.ApiTests/Verify/ContentUpdateTests.Should_get_content_by_version.verified.txt index 3e206dfe2..db7e237fb 100644 --- a/tools/TestSuite/TestSuite.ApiTests/Verify/ContentUpdateTests.Should_get_content_by_version.verified.txt +++ b/tools/TestSuite/TestSuite.ApiTests/Verify/ContentUpdateTests.Should_get_content_by_version.verified.txt @@ -1,5 +1,10 @@ { Data: { + Localized: { + custom: default, + de: default, + en: default + }, Number: 1 }, NewStatus: , diff --git a/tools/TestSuite/TestSuite.Shared/TestSuite.Shared.csproj b/tools/TestSuite/TestSuite.Shared/TestSuite.Shared.csproj index 56b8ebe82..41156df2f 100644 --- a/tools/TestSuite/TestSuite.Shared/TestSuite.Shared.csproj +++ b/tools/TestSuite/TestSuite.Shared/TestSuite.Shared.csproj @@ -16,8 +16,8 @@ - - + +