mirror of https://github.com/Squidex/squidex.git
committed by
GitHub
67 changed files with 1349 additions and 485 deletions
@ -0,0 +1,15 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Core.ExtractReferenceIds |
||||
|
{ |
||||
|
public enum Ids |
||||
|
{ |
||||
|
All, |
||||
|
ContentOnly |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,102 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// 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.ExtractReferenceIds; |
||||
|
using Squidex.Domain.Apps.Core.Schemas; |
||||
|
using Squidex.Infrastructure; |
||||
|
using Squidex.Infrastructure.Json.Objects; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Core.Operations.ExtractReferenceIds |
||||
|
{ |
||||
|
public class ReferenceFormattingTests |
||||
|
{ |
||||
|
private readonly LanguagesConfig languages = LanguagesConfig.English.Set(Language.DE); |
||||
|
|
||||
|
[Fact] |
||||
|
public void Should_format_data_with_reference_fields() |
||||
|
{ |
||||
|
var data = CreateData(); |
||||
|
|
||||
|
var schema = |
||||
|
new Schema("my-schema") |
||||
|
.AddString(1, "ref1", Partitioning.Invariant, |
||||
|
new StringFieldProperties { IsReferenceField = true }) |
||||
|
.AddString(2, "ref2", Partitioning.Invariant, |
||||
|
new StringFieldProperties { IsReferenceField = true }) |
||||
|
.AddString(3, "non-ref", Partitioning.Invariant); |
||||
|
|
||||
|
var formatted = data.FormatReferences(schema, languages); |
||||
|
|
||||
|
var expected = |
||||
|
JsonValue.Object() |
||||
|
.Add("en", "EN, 12") |
||||
|
.Add("de", "DE, 12"); |
||||
|
|
||||
|
Assert.Equal(expected, formatted); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Should_format_data_with_first_field_if_no_reference_field_defined() |
||||
|
{ |
||||
|
var data = CreateData(); |
||||
|
|
||||
|
var schema = CreateNoRefSchema(); |
||||
|
|
||||
|
var formatted = data.FormatReferences(schema, languages); |
||||
|
|
||||
|
var expected = |
||||
|
JsonValue.Object() |
||||
|
.Add("en", "EN") |
||||
|
.Add("de", "DE"); |
||||
|
|
||||
|
Assert.Equal(expected, formatted); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Should_return_default_value_if_no_value_found() |
||||
|
{ |
||||
|
var data = new NamedContentData(); |
||||
|
|
||||
|
var schema = CreateNoRefSchema(); |
||||
|
|
||||
|
var formatted = data.FormatReferences(schema, languages); |
||||
|
|
||||
|
var expected = |
||||
|
JsonValue.Object() |
||||
|
.Add("en", string.Empty) |
||||
|
.Add("de", string.Empty); |
||||
|
|
||||
|
Assert.Equal(expected, formatted); |
||||
|
} |
||||
|
|
||||
|
private static Schema CreateNoRefSchema() |
||||
|
{ |
||||
|
return new Schema("my-schema") |
||||
|
.AddString(1, "ref1", Partitioning.Invariant) |
||||
|
.AddString(2, "ref2", Partitioning.Invariant) |
||||
|
.AddString(3, "non-ref", Partitioning.Invariant); |
||||
|
} |
||||
|
|
||||
|
private static NamedContentData CreateData() |
||||
|
{ |
||||
|
return new NamedContentData() |
||||
|
.AddField("ref1", |
||||
|
new ContentFieldData() |
||||
|
.AddValue("en", "EN") |
||||
|
.AddValue("de", "DE")) |
||||
|
.AddField("ref2", |
||||
|
new ContentFieldData() |
||||
|
.AddValue("iv", 12)) |
||||
|
.AddField("non-ref", |
||||
|
new ContentFieldData() |
||||
|
.AddValue("iv", "Ignored")); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,215 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Threading.Tasks; |
||||
|
using FakeItEasy; |
||||
|
using Squidex.Domain.Apps.Core; |
||||
|
using Squidex.Domain.Apps.Core.Contents; |
||||
|
using Squidex.Domain.Apps.Core.Schemas; |
||||
|
using Squidex.Domain.Apps.Entities.TestHelpers; |
||||
|
using Squidex.Infrastructure; |
||||
|
using Squidex.Infrastructure.Json.Objects; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Entities.Contents |
||||
|
{ |
||||
|
public class ContentEnricherReferencesTests |
||||
|
{ |
||||
|
private readonly IContentWorkflow contentWorkflow = A.Fake<IContentWorkflow>(); |
||||
|
private readonly IContentQueryService contentQuery = A.Fake<IContentQueryService>(); |
||||
|
private readonly NamedId<Guid> appId = NamedId.Of(Guid.NewGuid(), "my-app"); |
||||
|
private readonly NamedId<Guid> refSchemaId1 = NamedId.Of(Guid.NewGuid(), "my-ref1"); |
||||
|
private readonly NamedId<Guid> refSchemaId2 = NamedId.Of(Guid.NewGuid(), "my-ref2"); |
||||
|
private readonly NamedId<Guid> schemaId = NamedId.Of(Guid.NewGuid(), "my-schema"); |
||||
|
private readonly Context requestContext; |
||||
|
private readonly ContentEnricher sut; |
||||
|
|
||||
|
public ContentEnricherReferencesTests() |
||||
|
{ |
||||
|
requestContext = new Context(Mocks.FrontendUser(), Mocks.App(appId, Language.DE)); |
||||
|
|
||||
|
var refSchemaDef = |
||||
|
new Schema("my-ref") |
||||
|
.AddString(1, "name", Partitioning.Invariant, |
||||
|
new StringFieldProperties { IsReferenceField = true }) |
||||
|
.AddNumber(2, "number", Partitioning.Invariant, |
||||
|
new NumberFieldProperties { IsReferenceField = true }); |
||||
|
|
||||
|
var schemaDef = |
||||
|
new Schema(schemaId.Name) |
||||
|
.AddReferences(1, "ref1", Partitioning.Invariant, new ReferencesFieldProperties |
||||
|
{ |
||||
|
ResolveReference = true, |
||||
|
IsListField = true, |
||||
|
MinItems = 1, |
||||
|
MaxItems = 1, |
||||
|
SchemaId = refSchemaId1.Id |
||||
|
}) |
||||
|
.AddReferences(2, "ref2", Partitioning.Invariant, new ReferencesFieldProperties |
||||
|
{ |
||||
|
ResolveReference = true, |
||||
|
IsListField = true, |
||||
|
MinItems = 1, |
||||
|
MaxItems = 1, |
||||
|
SchemaId = refSchemaId2.Id |
||||
|
}); |
||||
|
|
||||
|
void SetupSchema(NamedId<Guid> id, Schema def) |
||||
|
{ |
||||
|
var schemaEntity = Mocks.Schema(appId, id, def); |
||||
|
|
||||
|
A.CallTo(() => contentQuery.GetSchemaOrThrowAsync(requestContext, id.Id.ToString())) |
||||
|
.Returns(schemaEntity); |
||||
|
} |
||||
|
|
||||
|
SetupSchema(schemaId, schemaDef); |
||||
|
SetupSchema(refSchemaId1, refSchemaDef); |
||||
|
SetupSchema(refSchemaId2, refSchemaDef); |
||||
|
|
||||
|
sut = new ContentEnricher(new Lazy<IContentQueryService>(() => contentQuery), contentWorkflow); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public async Task Should_enrich_with_reference_data() |
||||
|
{ |
||||
|
var ref1_1 = CreateRefContent(Guid.NewGuid(), "ref1_1", 13); |
||||
|
var ref1_2 = CreateRefContent(Guid.NewGuid(), "ref1_2", 17); |
||||
|
var ref2_1 = CreateRefContent(Guid.NewGuid(), "ref2_1", 23); |
||||
|
var ref2_2 = CreateRefContent(Guid.NewGuid(), "ref2_2", 29); |
||||
|
|
||||
|
var source = new IContentEntity[] |
||||
|
{ |
||||
|
CreateContent(new Guid[] { ref1_1.Id }, new Guid[] { ref2_1.Id }), |
||||
|
CreateContent(new Guid[] { ref1_2.Id }, new Guid[] { ref2_2.Id }) |
||||
|
}; |
||||
|
|
||||
|
A.CallTo(() => contentQuery.QueryAsync(A<Context>.Ignored, A<IReadOnlyList<Guid>>.That.Matches(x => x.Count == 4))) |
||||
|
.Returns(ResultList.CreateFrom(4, ref1_1, ref1_2, ref2_1, ref2_2)); |
||||
|
|
||||
|
var enriched = await sut.EnrichAsync(source, requestContext); |
||||
|
|
||||
|
Assert.Equal( |
||||
|
new NamedContentData() |
||||
|
.AddField("ref1", |
||||
|
new ContentFieldData() |
||||
|
.AddJsonValue("iv", |
||||
|
JsonValue.Object() |
||||
|
.Add("en", "ref1_1, 13") |
||||
|
.Add("de", "ref1_1, 13"))) |
||||
|
.AddField("ref2", |
||||
|
new ContentFieldData() |
||||
|
.AddJsonValue("iv", |
||||
|
JsonValue.Object() |
||||
|
.Add("en", "ref2_1, 23") |
||||
|
.Add("de", "ref2_1, 23"))), |
||||
|
enriched.ElementAt(0).ReferenceData); |
||||
|
|
||||
|
Assert.Equal( |
||||
|
new NamedContentData() |
||||
|
.AddField("ref1", |
||||
|
new ContentFieldData() |
||||
|
.AddJsonValue("iv", |
||||
|
JsonValue.Object() |
||||
|
.Add("en", "ref1_2, 17") |
||||
|
.Add("de", "ref1_2, 17"))) |
||||
|
.AddField("ref2", |
||||
|
new ContentFieldData() |
||||
|
.AddJsonValue("iv", |
||||
|
JsonValue.Object() |
||||
|
.Add("en", "ref2_2, 29") |
||||
|
.Add("de", "ref2_2, 29"))), |
||||
|
enriched.ElementAt(1).ReferenceData); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public async Task Should_not_enrich_when_content_has_more_items() |
||||
|
{ |
||||
|
var ref1_1 = CreateRefContent(Guid.NewGuid(), "ref1_1", 13); |
||||
|
var ref1_2 = CreateRefContent(Guid.NewGuid(), "ref1_2", 17); |
||||
|
var ref2_1 = CreateRefContent(Guid.NewGuid(), "ref2_1", 23); |
||||
|
var ref2_2 = CreateRefContent(Guid.NewGuid(), "ref2_2", 29); |
||||
|
|
||||
|
var source = new IContentEntity[] |
||||
|
{ |
||||
|
CreateContent(new Guid[] { ref1_1.Id }, new Guid[] { ref2_1.Id, ref2_2.Id }), |
||||
|
CreateContent(new Guid[] { ref1_2.Id }, new Guid[] { ref2_1.Id, ref2_2.Id }) |
||||
|
}; |
||||
|
|
||||
|
A.CallTo(() => contentQuery.QueryAsync(A<Context>.Ignored, A<IReadOnlyList<Guid>>.That.Matches(x => x.Count == 4))) |
||||
|
.Returns(ResultList.CreateFrom(4, ref1_1, ref1_2, ref2_1, ref2_2)); |
||||
|
|
||||
|
var enriched = await sut.EnrichAsync(source, requestContext); |
||||
|
|
||||
|
Assert.Equal( |
||||
|
new NamedContentData() |
||||
|
.AddField("ref1", |
||||
|
new ContentFieldData() |
||||
|
.AddJsonValue("iv", |
||||
|
JsonValue.Object() |
||||
|
.Add("en", "ref1_1, 13") |
||||
|
.Add("de", "ref1_1, 13"))) |
||||
|
.AddField("ref2", |
||||
|
new ContentFieldData() |
||||
|
.AddJsonValue("iv", |
||||
|
JsonValue.Object() |
||||
|
.Add("en", "2 Reference(s)") |
||||
|
.Add("de", "2 Reference(s)"))), |
||||
|
enriched.ElementAt(0).ReferenceData); |
||||
|
|
||||
|
Assert.Equal( |
||||
|
new NamedContentData() |
||||
|
.AddField("ref1", |
||||
|
new ContentFieldData() |
||||
|
.AddJsonValue("iv", |
||||
|
JsonValue.Object() |
||||
|
.Add("en", "ref1_2, 17") |
||||
|
.Add("de", "ref1_2, 17"))) |
||||
|
.AddField("ref2", |
||||
|
new ContentFieldData() |
||||
|
.AddJsonValue("iv", |
||||
|
JsonValue.Object() |
||||
|
.Add("en", "2 Reference(s)") |
||||
|
.Add("de", "2 Reference(s)"))), |
||||
|
enriched.ElementAt(1).ReferenceData); |
||||
|
} |
||||
|
|
||||
|
private IEnrichedContentEntity CreateContent(Guid[] ref1, Guid[] ref2) |
||||
|
{ |
||||
|
return new ContentEntity |
||||
|
{ |
||||
|
DataDraft = |
||||
|
new NamedContentData() |
||||
|
.AddField("ref1", |
||||
|
new ContentFieldData() |
||||
|
.AddJsonValue("iv", JsonValue.Array(ref1.Select(x => x.ToString()).ToArray()))) |
||||
|
.AddField("ref2", |
||||
|
new ContentFieldData() |
||||
|
.AddJsonValue("iv", JsonValue.Array(ref2.Select(x => x.ToString()).ToArray()))), |
||||
|
SchemaId = schemaId |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
private IEnrichedContentEntity CreateRefContent(Guid id, string name, int number) |
||||
|
{ |
||||
|
return new ContentEntity |
||||
|
{ |
||||
|
DataDraft = |
||||
|
new NamedContentData() |
||||
|
.AddField("name", |
||||
|
new ContentFieldData() |
||||
|
.AddValue("iv", name)) |
||||
|
.AddField("number", |
||||
|
new ContentFieldData() |
||||
|
.AddValue("iv", number)), |
||||
|
Id = id |
||||
|
}; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,67 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System; |
||||
|
using System.Security.Claims; |
||||
|
using FakeItEasy; |
||||
|
using Squidex.Domain.Apps.Core.Apps; |
||||
|
using Squidex.Domain.Apps.Core.Schemas; |
||||
|
using Squidex.Domain.Apps.Entities.Apps; |
||||
|
using Squidex.Domain.Apps.Entities.Schemas; |
||||
|
using Squidex.Infrastructure; |
||||
|
using Squidex.Infrastructure.Security; |
||||
|
using Squidex.Shared; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Entities.TestHelpers |
||||
|
{ |
||||
|
public static class Mocks |
||||
|
{ |
||||
|
public static IAppEntity App(NamedId<Guid> appId, params Language[] languages) |
||||
|
{ |
||||
|
var config = LanguagesConfig.English; |
||||
|
|
||||
|
foreach (var language in languages) |
||||
|
{ |
||||
|
config = config.Set(language); |
||||
|
} |
||||
|
|
||||
|
var app = A.Fake<IAppEntity>(); |
||||
|
|
||||
|
A.CallTo(() => app.Id).Returns(appId.Id); |
||||
|
A.CallTo(() => app.Name).Returns(appId.Name); |
||||
|
A.CallTo(() => app.LanguagesConfig).Returns(config); |
||||
|
|
||||
|
return app; |
||||
|
} |
||||
|
|
||||
|
public static ISchemaEntity Schema(NamedId<Guid> appId, NamedId<Guid> schemaId, Schema schemaDef = null) |
||||
|
{ |
||||
|
var schema = A.Fake<ISchemaEntity>(); |
||||
|
|
||||
|
A.CallTo(() => schema.Id).Returns(schemaId.Id); |
||||
|
A.CallTo(() => schema.AppId).Returns(appId); |
||||
|
A.CallTo(() => schema.SchemaDef).Returns(schemaDef ?? new Schema(schemaId.Name)); |
||||
|
|
||||
|
return schema; |
||||
|
} |
||||
|
|
||||
|
public static ClaimsPrincipal FrontendUser(string role = null) |
||||
|
{ |
||||
|
var claimsIdentity = new ClaimsIdentity(); |
||||
|
var claimsPrincipal = new ClaimsPrincipal(claimsIdentity); |
||||
|
|
||||
|
claimsIdentity.AddClaim(new Claim(OpenIdClaims.ClientId, DefaultClients.Frontend)); |
||||
|
|
||||
|
if (role != null) |
||||
|
{ |
||||
|
claimsIdentity.AddClaim(new Claim(ClaimTypes.Role, role)); |
||||
|
} |
||||
|
|
||||
|
return claimsPrincipal; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue