From 69736f5b13125182577e2686d2a2c75b3dc8a0fe Mon Sep 17 00:00:00 2001 From: Sebastian Stehle Date: Tue, 13 Nov 2018 19:20:21 +0100 Subject: [PATCH] * Bugfix with deleting items. * Bugfix for arrays with strings. --- .../Squidex.Extensions.csproj | 6 +- .../Squidex.Domain.Apps.Core.Model.csproj | 2 +- .../ConvertContent/ContentConverter.cs | 55 ++++++++++++ ...Squidex.Domain.Apps.Core.Operations.csproj | 2 +- .../Contents/Extensions.cs | 37 -------- .../Contents/MongoContentDraftCollection.cs | 1 + .../MongoContentPublishedCollection.cs | 1 + ...quidex.Domain.Apps.Entities.MongoDb.csproj | 2 +- .../GraphQL/Types/Utils/GuidGraphType.cs | 55 ------------ .../Squidex.Domain.Apps.Entities.csproj | 8 +- .../Squidex.Domain.Apps.Events.csproj | 2 +- .../Squidex.Domain.Users.MongoDb.csproj | 4 +- .../Squidex.Domain.Users.csproj | 2 +- .../Squidex.Infrastructure.MongoDb.csproj | 4 +- .../Squidex.Infrastructure.csproj | 10 +-- src/Squidex.Shared/Permissions.cs | 2 +- .../Schemas/SchemaFieldsController.cs | 3 + src/Squidex/Squidex.csproj | 10 +-- .../ConvertContent/ContentConversionTests.cs | 86 +++++++++++++++++++ .../Squidex.Domain.Apps.Core.Tests.csproj | 6 +- .../Squidex.Domain.Apps.Entities.Tests.csproj | 10 +-- .../Squidex.Domain.Users.Tests.csproj | 6 +- .../Squidex.Infrastructure.Tests.csproj | 6 +- tests/Squidex.Tests/Squidex.Tests.csproj | 6 +- tools/Migrate_00/Migrate_00.csproj | 2 +- 25 files changed, 191 insertions(+), 137 deletions(-) delete mode 100644 src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Utils/GuidGraphType.cs diff --git a/extensions/Squidex.Extensions/Squidex.Extensions.csproj b/extensions/Squidex.Extensions/Squidex.Extensions.csproj index 3edb1180c..5ebf0cfef 100644 --- a/extensions/Squidex.Extensions/Squidex.Extensions.csproj +++ b/extensions/Squidex.Extensions/Squidex.Extensions.csproj @@ -11,12 +11,12 @@ - - + + - + diff --git a/src/Squidex.Domain.Apps.Core.Model/Squidex.Domain.Apps.Core.Model.csproj b/src/Squidex.Domain.Apps.Core.Model/Squidex.Domain.Apps.Core.Model.csproj index 4b2e0960c..320081eda 100644 --- a/src/Squidex.Domain.Apps.Core.Model/Squidex.Domain.Apps.Core.Model.csproj +++ b/src/Squidex.Domain.Apps.Core.Model/Squidex.Domain.Apps.Core.Model.csproj @@ -8,7 +8,7 @@ True - + all runtime; build; native; contentfiles; analyzers diff --git a/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/ContentConverter.cs b/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/ContentConverter.cs index 52284631d..de8e250a7 100644 --- a/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/ContentConverter.cs +++ b/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/ContentConverter.cs @@ -7,6 +7,10 @@ using System; using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using Newtonsoft.Json.Linq; using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.Schemas; using Squidex.Infrastructure; @@ -18,6 +22,57 @@ namespace Squidex.Domain.Apps.Core.ConvertContent private static readonly Func KeyNameResolver = f => f.Name; private static readonly Func KeyIdResolver = f => f.Id; + public static string ToFullText(this ContentData data, int maxTotalLength = 1024 * 1024, int maxFieldLength = 1000, string separator = " ") + { + var stringBuilder = new StringBuilder(); + + foreach (var value in data.Values.SelectMany(x => x.Values)) + { + AppendText(value, stringBuilder, maxFieldLength, separator, false); + } + + var result = stringBuilder.ToString(); + + if (result.Length > maxTotalLength) + { + result = result.Substring(0, maxTotalLength); + } + + return result; + } + + private static void AppendText(JToken value, StringBuilder stringBuilder, int maxFieldLength, string separator, bool allowObjects) + { + if (value?.Type == JTokenType.String) + { + var text = ((JValue)value).ToString(CultureInfo.InvariantCulture); + + if (text.Length <= maxFieldLength) + { + if (stringBuilder.Length > 0) + { + stringBuilder.Append(separator); + } + + stringBuilder.Append(text); + } + } + else if (value?.Type == JTokenType.Array) + { + foreach (var item in value) + { + AppendText(item, stringBuilder, maxFieldLength, separator, true); + } + } + else if (value?.Type == JTokenType.Object && allowObjects) + { + foreach (JProperty property in value) + { + AppendText(property.Value, stringBuilder, maxFieldLength, separator, true); + } + } + } + public static NamedContentData ConvertId2Name(this IdContentData content, Schema schema, params FieldConverter[] converters) { Guard.NotNull(schema, nameof(schema)); diff --git a/src/Squidex.Domain.Apps.Core.Operations/Squidex.Domain.Apps.Core.Operations.csproj b/src/Squidex.Domain.Apps.Core.Operations/Squidex.Domain.Apps.Core.Operations.csproj index 4a1d40b7e..383bb37ae 100644 --- a/src/Squidex.Domain.Apps.Core.Operations/Squidex.Domain.Apps.Core.Operations.csproj +++ b/src/Squidex.Domain.Apps.Core.Operations/Squidex.Domain.Apps.Core.Operations.csproj @@ -17,7 +17,7 @@ - + diff --git a/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Extensions.cs b/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Extensions.cs index c1f982348..c3fc170a7 100644 --- a/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Extensions.cs +++ b/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Extensions.cs @@ -7,10 +7,7 @@ using System; using System.Collections.Generic; -using System.Globalization; using System.Linq; -using System.Text; -using Newtonsoft.Json.Linq; using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.ConvertContent; using Squidex.Domain.Apps.Core.ExtractReferenceIds; @@ -20,8 +17,6 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Contents { public static class Extensions { - private const int MaxLength = 1024 * 1024; - public static List ToReferencedIds(this IdContentData data, Schema schema) { return data.GetReferencedIds(schema).ToList(); @@ -46,37 +41,5 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Contents FieldConverters.ForNestedName2Id( ValueConverters.EncodeJson())); } - - public static string ToFullText(this ContentData data) - { - var stringBuilder = new StringBuilder(); - - foreach (var text in data.Values.SelectMany(x => x.Values).Where(x => x != null).OfType()) - { - if (text.Type == JTokenType.String) - { - var value = text.ToString(CultureInfo.InvariantCulture); - - if (value.Length < 1000) - { - if (stringBuilder.Length > 0) - { - stringBuilder.Append(" "); - } - - stringBuilder.Append(text); - } - } - } - - var result = stringBuilder.ToString(); - - if (result.Length > MaxLength) - { - result = result.Substring(MaxLength); - } - - return result; - } } } diff --git a/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentDraftCollection.cs b/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentDraftCollection.cs index 6ad2c7651..2c80690f7 100644 --- a/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentDraftCollection.cs +++ b/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentDraftCollection.cs @@ -12,6 +12,7 @@ using System.Threading; using System.Threading.Tasks; using MongoDB.Driver; using NodaTime; +using Squidex.Domain.Apps.Core.ConvertContent; using Squidex.Domain.Apps.Entities.Apps; using Squidex.Domain.Apps.Entities.Contents; using Squidex.Domain.Apps.Entities.Contents.State; diff --git a/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentPublishedCollection.cs b/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentPublishedCollection.cs index 8f2c424e9..97ca68a3d 100644 --- a/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentPublishedCollection.cs +++ b/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentPublishedCollection.cs @@ -9,6 +9,7 @@ using System; using System.Threading; using System.Threading.Tasks; using MongoDB.Driver; +using Squidex.Domain.Apps.Core.ConvertContent; using Squidex.Domain.Apps.Entities.Apps; using Squidex.Domain.Apps.Entities.Contents; using Squidex.Domain.Apps.Entities.Schemas; diff --git a/src/Squidex.Domain.Apps.Entities.MongoDb/Squidex.Domain.Apps.Entities.MongoDb.csproj b/src/Squidex.Domain.Apps.Entities.MongoDb/Squidex.Domain.Apps.Entities.MongoDb.csproj index 046841149..6fe43a66d 100644 --- a/src/Squidex.Domain.Apps.Entities.MongoDb/Squidex.Domain.Apps.Entities.MongoDb.csproj +++ b/src/Squidex.Domain.Apps.Entities.MongoDb/Squidex.Domain.Apps.Entities.MongoDb.csproj @@ -16,7 +16,7 @@ - + diff --git a/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Utils/GuidGraphType.cs b/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Utils/GuidGraphType.cs deleted file mode 100644 index bbfc8ea5b..000000000 --- a/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Utils/GuidGraphType.cs +++ /dev/null @@ -1,55 +0,0 @@ -// ========================================================================== -// Squidex Headless CMS -// ========================================================================== -// Copyright (c) Squidex UG (haftungsbeschraenkt) -// All rights reserved. Licensed under the MIT license. -// ========================================================================== - -using System; -using GraphQL.Language.AST; -using GraphQL.Types; - -namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types.Utils -{ - public sealed class GuidGraphType : ScalarGraphType - { - public GuidGraphType() - { - Name = "Guid"; - - Description = "The `Guid` scalar type global unique identifier"; - } - - public override object Serialize(object value) - { - return ParseValue(value)?.ToString(); - } - - public override object ParseValue(object value) - { - if (value is Guid guid) - { - return guid; - } - - var inputValue = value?.ToString().Trim('"'); - - if (Guid.TryParse(inputValue, out guid)) - { - return guid; - } - - return null; - } - - public override object ParseLiteral(IValue value) - { - if (value is StringValue stringValue) - { - return ParseValue(stringValue.Value); - } - - return null; - } - } -} diff --git a/src/Squidex.Domain.Apps.Entities/Squidex.Domain.Apps.Entities.csproj b/src/Squidex.Domain.Apps.Entities/Squidex.Domain.Apps.Entities.csproj index f3c64022d..c5351edeb 100644 --- a/src/Squidex.Domain.Apps.Entities/Squidex.Domain.Apps.Entities.csproj +++ b/src/Squidex.Domain.Apps.Entities/Squidex.Domain.Apps.Entities.csproj @@ -14,13 +14,13 @@ - - + + all runtime; build; native; contentfiles; analyzers - - + + diff --git a/src/Squidex.Domain.Apps.Events/Squidex.Domain.Apps.Events.csproj b/src/Squidex.Domain.Apps.Events/Squidex.Domain.Apps.Events.csproj index b6264eb9b..f93dbb6e2 100644 --- a/src/Squidex.Domain.Apps.Events/Squidex.Domain.Apps.Events.csproj +++ b/src/Squidex.Domain.Apps.Events/Squidex.Domain.Apps.Events.csproj @@ -12,7 +12,7 @@ - + diff --git a/src/Squidex.Domain.Users.MongoDb/Squidex.Domain.Users.MongoDb.csproj b/src/Squidex.Domain.Users.MongoDb/Squidex.Domain.Users.MongoDb.csproj index 56fc1237c..1406f716e 100644 --- a/src/Squidex.Domain.Users.MongoDb/Squidex.Domain.Users.MongoDb.csproj +++ b/src/Squidex.Domain.Users.MongoDb/Squidex.Domain.Users.MongoDb.csproj @@ -14,9 +14,9 @@ - + - + diff --git a/src/Squidex.Domain.Users/Squidex.Domain.Users.csproj b/src/Squidex.Domain.Users/Squidex.Domain.Users.csproj index 539128d44..410d36a0c 100644 --- a/src/Squidex.Domain.Users/Squidex.Domain.Users.csproj +++ b/src/Squidex.Domain.Users/Squidex.Domain.Users.csproj @@ -11,7 +11,7 @@ - + diff --git a/src/Squidex.Infrastructure.MongoDb/Squidex.Infrastructure.MongoDb.csproj b/src/Squidex.Infrastructure.MongoDb/Squidex.Infrastructure.MongoDb.csproj index e158851ac..92739b78d 100644 --- a/src/Squidex.Infrastructure.MongoDb/Squidex.Infrastructure.MongoDb.csproj +++ b/src/Squidex.Infrastructure.MongoDb/Squidex.Infrastructure.MongoDb.csproj @@ -11,8 +11,8 @@ - - + + diff --git a/src/Squidex.Infrastructure/Squidex.Infrastructure.csproj b/src/Squidex.Infrastructure/Squidex.Infrastructure.csproj index 11d4cf7ba..7193829fb 100644 --- a/src/Squidex.Infrastructure/Squidex.Infrastructure.csproj +++ b/src/Squidex.Infrastructure/Squidex.Infrastructure.csproj @@ -11,21 +11,21 @@ - + all runtime; build; native; contentfiles; analyzers - - + + - + - + diff --git a/src/Squidex.Shared/Permissions.cs b/src/Squidex.Shared/Permissions.cs index c08e48974..c49784d7f 100644 --- a/src/Squidex.Shared/Permissions.cs +++ b/src/Squidex.Shared/Permissions.cs @@ -170,7 +170,7 @@ namespace Squidex.Shared var result = matching - .Select(x => x.Id.Split('.')) + .Select(x => x.Id.Split('.')).Where(x => x.Length > 2) .Select(x => x[2]) .Distinct() .ToArray(); diff --git a/src/Squidex/Areas/Api/Controllers/Schemas/SchemaFieldsController.cs b/src/Squidex/Areas/Api/Controllers/Schemas/SchemaFieldsController.cs index 57aeb8fb0..00850058e 100644 --- a/src/Squidex/Areas/Api/Controllers/Schemas/SchemaFieldsController.cs +++ b/src/Squidex/Areas/Api/Controllers/Schemas/SchemaFieldsController.cs @@ -439,6 +439,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas [HttpPut] [Route("apps/{app}/schemas/{name}/fields/{parentId:long}/nested/{id:long}/disable/")] [ProducesResponseType(typeof(ErrorDto), 400)] + [ApiPermission(Permissions.AppSchemasUpdate)] [ApiCosts(1)] public async Task DisableNestedField(string app, string name, long parentId, long id) { @@ -460,6 +461,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas /// [HttpDelete] [Route("apps/{app}/schemas/{name}/fields/{id:long}/")] + [ApiPermission(Permissions.AppSchemasUpdate)] [ApiCosts(1)] public async Task DeleteField(string app, string name, long id) { @@ -482,6 +484,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas /// [HttpDelete] [Route("apps/{app}/schemas/{name}/fields/{parentId:long}/nested/{id:long}/")] + [ApiPermission(Permissions.AppSchemasUpdate)] [ApiCosts(1)] public async Task DeleteNestedField(string app, string name, long parentId, long id) { diff --git a/src/Squidex/Squidex.csproj b/src/Squidex/Squidex.csproj index 6ef23a2c1..81922a4b1 100644 --- a/src/Squidex/Squidex.csproj +++ b/src/Squidex/Squidex.csproj @@ -60,12 +60,12 @@ - + - + @@ -77,15 +77,15 @@ - - + + - + diff --git a/tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/ContentConversionTests.cs b/tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/ContentConversionTests.cs index 7081b61bc..2415089c4 100644 --- a/tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/ContentConversionTests.cs +++ b/tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/ContentConversionTests.cs @@ -5,6 +5,7 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== +using Newtonsoft.Json.Linq; using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.ConvertContent; using Squidex.Domain.Apps.Core.Schemas; @@ -148,5 +149,90 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent Assert.True(lhs.Equals((object)rhs)); Assert.Equal(lhs.GetHashCode(), rhs.GetHashCode()); } + + [Fact] + public void Should_extract_strings() + { + var input = + new NamedContentData() + .AddField("field1", + new ContentFieldData() + .AddValue("en", "hello")) + .AddField("field2", + new ContentFieldData() + .AddValue("iv", "world")); + + var result = input.ToFullText(); + + Assert.Equal("hello world", result); + } + + [Fact] + public void Should_extract_strings_from_arrays() + { + var input = + new NamedContentData() + .AddField("field1", + new ContentFieldData() + .AddValue("en", new JArray("hello", "loved"))) + .AddField("field2", + new ContentFieldData() + .AddValue("iv", "world")); + + var result = input.ToFullText(); + + Assert.Equal("hello loved world", result); + } + + [Fact] + public void Should_extract_strings_from_objects() + { + var input = + new NamedContentData() + .AddField("field1", + new ContentFieldData() + .AddValue("en", new JArray(new JObject(new JProperty("p1", "hello"))))) + .AddField("field2", + new ContentFieldData() + .AddValue("iv", "world")); + + var result = input.ToFullText(); + + Assert.Equal("hello world", result); + } + + [Fact] + public void Should_skip_long_strings() + { + var input = + new NamedContentData() + .AddField("field1", + new ContentFieldData() + .AddValue("en", "hello")) + .AddField("field2", + new ContentFieldData() + .AddValue("iv", "you")); + + var result = input.ToFullText(maxFieldLength: 3); + + Assert.Equal("you", result); + } + + [Fact] + public void Should_trim_long_results() + { + var input = + new NamedContentData() + .AddField("field1", + new ContentFieldData() + .AddValue("en", "hello")) + .AddField("field2", + new ContentFieldData() + .AddValue("iv", "you")); + + var result = input.ToFullText(maxTotalLength: 7); + + Assert.Equal("hello y", result); + } } } diff --git a/tests/Squidex.Domain.Apps.Core.Tests/Squidex.Domain.Apps.Core.Tests.csproj b/tests/Squidex.Domain.Apps.Core.Tests/Squidex.Domain.Apps.Core.Tests.csproj index c8cd55721..9e4d01a77 100644 --- a/tests/Squidex.Domain.Apps.Core.Tests/Squidex.Domain.Apps.Core.Tests.csproj +++ b/tests/Squidex.Domain.Apps.Core.Tests/Squidex.Domain.Apps.Core.Tests.csproj @@ -12,13 +12,13 @@ - + - - + + all runtime; build; native; contentfiles; analyzers diff --git a/tests/Squidex.Domain.Apps.Entities.Tests/Squidex.Domain.Apps.Entities.Tests.csproj b/tests/Squidex.Domain.Apps.Entities.Tests/Squidex.Domain.Apps.Entities.Tests.csproj index 60937e067..d9a8019ce 100644 --- a/tests/Squidex.Domain.Apps.Entities.Tests/Squidex.Domain.Apps.Entities.Tests.csproj +++ b/tests/Squidex.Domain.Apps.Entities.Tests/Squidex.Domain.Apps.Entities.Tests.csproj @@ -21,15 +21,15 @@ - - + + - + - - + + all runtime; build; native; contentfiles; analyzers diff --git a/tests/Squidex.Domain.Users.Tests/Squidex.Domain.Users.Tests.csproj b/tests/Squidex.Domain.Users.Tests/Squidex.Domain.Users.Tests.csproj index 35548164f..b2835ab27 100644 --- a/tests/Squidex.Domain.Users.Tests/Squidex.Domain.Users.Tests.csproj +++ b/tests/Squidex.Domain.Users.Tests/Squidex.Domain.Users.Tests.csproj @@ -13,13 +13,13 @@ - + - - + + all runtime; build; native; contentfiles; analyzers diff --git a/tests/Squidex.Infrastructure.Tests/Squidex.Infrastructure.Tests.csproj b/tests/Squidex.Infrastructure.Tests/Squidex.Infrastructure.Tests.csproj index 337b00a58..079cd0d05 100644 --- a/tests/Squidex.Infrastructure.Tests/Squidex.Infrastructure.Tests.csproj +++ b/tests/Squidex.Infrastructure.Tests/Squidex.Infrastructure.Tests.csproj @@ -13,7 +13,7 @@ - + @@ -21,8 +21,8 @@ - - + + all runtime; build; native; contentfiles; analyzers diff --git a/tests/Squidex.Tests/Squidex.Tests.csproj b/tests/Squidex.Tests/Squidex.Tests.csproj index bfb791e64..1eae1f195 100644 --- a/tests/Squidex.Tests/Squidex.Tests.csproj +++ b/tests/Squidex.Tests/Squidex.Tests.csproj @@ -15,11 +15,11 @@ - + - - + + all runtime; build; native; contentfiles; analyzers diff --git a/tools/Migrate_00/Migrate_00.csproj b/tools/Migrate_00/Migrate_00.csproj index c3b7890f3..c6a26e3cf 100644 --- a/tools/Migrate_00/Migrate_00.csproj +++ b/tools/Migrate_00/Migrate_00.csproj @@ -5,7 +5,7 @@ 2.1.1 - +