Browse Source

Multiple references in core model.

pull/422/head
Sebastian 7 years ago
parent
commit
5c81242e1a
  1. 19
      src/Squidex.Domain.Apps.Core.Model/Schemas/ReferencesFieldProperties.cs
  2. 6
      src/Squidex.Domain.Apps.Core.Model/Schemas/SchemaExtensions.cs
  3. 2
      src/Squidex.Domain.Apps.Core.Operations/ExtractReferenceIds/ReferencesCleaner.cs
  4. 7
      src/Squidex.Domain.Apps.Core.Operations/ExtractReferenceIds/ReferencesExtractor.cs
  5. 5
      src/Squidex.Domain.Apps.Core.Operations/ValidateContent/FieldValueValidatorsFactory.cs
  6. 44
      src/Squidex.Domain.Apps.Core.Operations/ValidateContent/ValidationContext.cs
  7. 22
      src/Squidex.Domain.Apps.Core.Operations/ValidateContent/Validators/ReferencesValidator.cs
  8. 2
      src/Squidex.Domain.Apps.Core.Operations/ValidateContent/Validators/UniqueValidator.cs
  9. 1
      src/Squidex.Domain.Users/UserManagerExtensions.cs
  10. 2
      tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/NumberFieldTests.cs
  11. 51
      tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/ReferencesFieldTests.cs
  12. 2
      tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/StringFieldTests.cs
  13. 1
      tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/UIFieldTests.cs
  14. 15
      tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/ValidationTestExtensions.cs
  15. 6
      tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/Validators/UniqueValidatorTests.cs
  16. 1
      tests/Squidex.Domain.Apps.Core.Tests/Squidex.Domain.Apps.Core.Tests.csproj
  17. 11
      tests/Squidex.Domain.Apps.Core.Tests/TestUtils.cs

19
src/Squidex.Domain.Apps.Core.Model/Schemas/ReferencesFieldProperties.cs

@ -6,6 +6,8 @@
// ========================================================================== // ==========================================================================
using System; using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace Squidex.Domain.Apps.Core.Schemas namespace Squidex.Domain.Apps.Core.Schemas
{ {
@ -21,7 +23,22 @@ namespace Squidex.Domain.Apps.Core.Schemas
public ReferencesFieldEditor Editor { get; set; } public ReferencesFieldEditor Editor { get; set; }
public Guid SchemaId { get; set; } public ReadOnlyCollection<Guid> SchemaIds { get; set; }
public Guid SchemaId
{
set
{
if (value != default)
{
SchemaIds = new ReadOnlyCollection<Guid>(new List<Guid> { value });
}
else
{
SchemaIds = null;
}
}
}
public override T Accept<T>(IFieldPropertiesVisitor<T> visitor) public override T Accept<T>(IFieldPropertiesVisitor<T> visitor)
{ {

6
src/Squidex.Domain.Apps.Core.Model/Schemas/SchemaExtensions.cs

@ -54,11 +54,15 @@ namespace Squidex.Domain.Apps.Core.Schemas
return schema.Properties.Label.WithFallback(schema.TypeName()); return schema.Properties.Label.WithFallback(schema.TypeName());
} }
public static Guid SingleId(this ReferencesFieldProperties properties)
{
return properties.SchemaIds?.Count == 1 ? properties.SchemaIds[0] : Guid.Empty;
}
public static IEnumerable<IField<ReferencesFieldProperties>> ResolvingReferences(this Schema schema) public static IEnumerable<IField<ReferencesFieldProperties>> ResolvingReferences(this Schema schema)
{ {
return schema.Fields.OfType<IField<ReferencesFieldProperties>>() return schema.Fields.OfType<IField<ReferencesFieldProperties>>()
.Where(x => .Where(x =>
x.Properties.SchemaId != Guid.Empty &&
x.Properties.ResolveReference && x.Properties.ResolveReference &&
x.Properties.MaxItems == 1 && x.Properties.MaxItems == 1 &&
(x.Properties.IsListField || schema.Fields.Count == 1)); (x.Properties.IsListField || schema.Fields.Count == 1));

2
src/Squidex.Domain.Apps.Core.Operations/ExtractReferenceIds/ReferencesCleaner.cs

@ -36,7 +36,7 @@ namespace Squidex.Domain.Apps.Core.ExtractReferenceIds
public IJsonValue Visit(IField<ReferencesFieldProperties> field) public IJsonValue Visit(IField<ReferencesFieldProperties> field)
{ {
if (oldReferences.Contains(field.Properties.SchemaId)) if (oldReferences.Contains(field.Properties.SingleId()))
{ {
return JsonValue.Array(); return JsonValue.Array();
} }

7
src/Squidex.Domain.Apps.Core.Operations/ExtractReferenceIds/ReferencesExtractor.cs

@ -62,9 +62,12 @@ namespace Squidex.Domain.Apps.Core.ExtractReferenceIds
{ {
var ids = value.ToGuidSet(); var ids = value.ToGuidSet();
if (strategy == Ids.All && field.Properties.SchemaId != Guid.Empty) if (strategy == Ids.All && field.Properties.SchemaIds != null)
{ {
ids.Add(field.Properties.SchemaId); foreach (var schemaId in field.Properties.SchemaIds)
{
ids.Add(schemaId);
}
} }
return ids; return ids;

5
src/Squidex.Domain.Apps.Core.Operations/ValidateContent/FieldValueValidatorsFactory.cs

@ -134,10 +134,7 @@ namespace Squidex.Domain.Apps.Core.ValidateContent
yield return new UniqueValuesValidator<Guid>(); yield return new UniqueValuesValidator<Guid>();
} }
if (field.Properties.SchemaId != Guid.Empty) yield return new ReferencesValidator(field.Properties.SchemaIds);
{
yield return new ReferencesValidator(field.Properties.SchemaId);
}
} }
public IEnumerable<IValidator> Visit(IField<StringFieldProperties> field) public IEnumerable<IValidator> Visit(IField<StringFieldProperties> field)

44
src/Squidex.Domain.Apps.Core.Operations/ValidateContent/ValidationContext.cs

@ -14,7 +14,9 @@ using Squidex.Infrastructure.Queries;
namespace Squidex.Domain.Apps.Core.ValidateContent namespace Squidex.Domain.Apps.Core.ValidateContent
{ {
public delegate Task<IReadOnlyList<Guid>> CheckContents(Guid schemaId, FilterNode<ClrValue> filter); public delegate Task<IReadOnlyList<(Guid SchemaId, Guid Id)>> CheckContents(Guid schemaId, FilterNode<ClrValue> filter);
public delegate Task<IReadOnlyList<(Guid SchemaId, Guid Id)>> CheckContentsByIds(HashSet<Guid> ids);
public delegate Task<IReadOnlyList<IAssetInfo>> CheckAssets(IEnumerable<Guid> ids); public delegate Task<IReadOnlyList<IAssetInfo>> CheckAssets(IEnumerable<Guid> ids);
@ -23,6 +25,7 @@ namespace Squidex.Domain.Apps.Core.ValidateContent
private readonly Guid contentId; private readonly Guid contentId;
private readonly Guid schemaId; private readonly Guid schemaId;
private readonly CheckContents checkContent; private readonly CheckContents checkContent;
private readonly CheckContentsByIds checkContentByIds;
private readonly CheckAssets checkAsset; private readonly CheckAssets checkAsset;
private readonly ImmutableQueue<string> propertyPath; private readonly ImmutableQueue<string> propertyPath;
@ -47,8 +50,9 @@ namespace Squidex.Domain.Apps.Core.ValidateContent
Guid contentId, Guid contentId,
Guid schemaId, Guid schemaId,
CheckContents checkContent, CheckContents checkContent,
CheckContentsByIds checkContentsByIds,
CheckAssets checkAsset) CheckAssets checkAsset)
: this(contentId, schemaId, checkContent, checkAsset, ImmutableQueue<string>.Empty, false) : this(contentId, schemaId, checkContent, checkContentsByIds, checkAsset, ImmutableQueue<string>.Empty, false)
{ {
} }
@ -56,16 +60,19 @@ namespace Squidex.Domain.Apps.Core.ValidateContent
Guid contentId, Guid contentId,
Guid schemaId, Guid schemaId,
CheckContents checkContent, CheckContents checkContent,
CheckContentsByIds checkContentByIds,
CheckAssets checkAsset, CheckAssets checkAsset,
ImmutableQueue<string> propertyPath, ImmutableQueue<string> propertyPath,
bool isOptional) bool isOptional)
{ {
Guard.NotNull(checkAsset, nameof(checkAsset)); Guard.NotNull(checkAsset, nameof(checkAsset));
Guard.NotNull(checkContent, nameof(checkAsset)); Guard.NotNull(checkContent, nameof(checkContent));
Guard.NotNull(checkContentByIds, nameof(checkContentByIds));
this.propertyPath = propertyPath; this.propertyPath = propertyPath;
this.checkContent = checkContent; this.checkContent = checkContent;
this.checkContentByIds = checkContentByIds;
this.checkAsset = checkAsset; this.checkAsset = checkAsset;
this.contentId = contentId; this.contentId = contentId;
@ -76,17 +83,40 @@ namespace Squidex.Domain.Apps.Core.ValidateContent
public ValidationContext Optional(bool isOptional) public ValidationContext Optional(bool isOptional)
{ {
return isOptional == IsOptional ? this : new ValidationContext(contentId, schemaId, checkContent, checkAsset, propertyPath, isOptional); return isOptional == IsOptional ? this : OptionalCore(isOptional);
}
private ValidationContext OptionalCore(bool isOptional)
{
return new ValidationContext(
contentId,
schemaId,
checkContent,
checkContentByIds,
checkAsset,
propertyPath,
isOptional);
} }
public ValidationContext Nested(string property) public ValidationContext Nested(string property)
{ {
return new ValidationContext(contentId, schemaId, checkContent, checkAsset, propertyPath.Enqueue(property), IsOptional); return new ValidationContext(
contentId, schemaId,
checkContent,
checkContentByIds,
checkAsset,
propertyPath.Enqueue(property),
IsOptional);
}
public Task<IReadOnlyList<(Guid SchemaId, Guid Id)>> GetContentIdsAsync(HashSet<Guid> ids)
{
return checkContentByIds(ids);
} }
public Task<IReadOnlyList<Guid>> GetContentIdsAsync(Guid validatedSchemaId, FilterNode<ClrValue> filter) public Task<IReadOnlyList<(Guid SchemaId, Guid Id)>> GetContentIdsAsync(Guid schemaId, FilterNode<ClrValue> filter)
{ {
return checkContent(validatedSchemaId, filter); return checkContent(schemaId, filter);
} }
public Task<IReadOnlyList<IAssetInfo>> GetAssetInfosAsync(IEnumerable<Guid> assetId) public Task<IReadOnlyList<IAssetInfo>> GetAssetInfosAsync(IEnumerable<Guid> assetId)

22
src/Squidex.Domain.Apps.Core.Operations/ValidateContent/Validators/ReferencesValidator.cs

@ -9,35 +9,37 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Squidex.Infrastructure.Queries; using Squidex.Infrastructure;
namespace Squidex.Domain.Apps.Core.ValidateContent.Validators namespace Squidex.Domain.Apps.Core.ValidateContent.Validators
{ {
public sealed class ReferencesValidator : IValidator public sealed class ReferencesValidator : IValidator
{ {
private static readonly PropertyPath Path = "Id"; private readonly IEnumerable<Guid> schemaIds;
private readonly Guid schemaId; public ReferencesValidator(IEnumerable<Guid> schemaIds)
public ReferencesValidator(Guid schemaId)
{ {
this.schemaId = schemaId; this.schemaIds = schemaIds;
} }
public async Task ValidateAsync(object value, ValidationContext context, AddError addError) public async Task ValidateAsync(object value, ValidationContext context, AddError addError)
{ {
if (value is ICollection<Guid> contentIds) if (value is ICollection<Guid> contentIds)
{ {
var filter = ClrFilter.In(Path, contentIds.ToList()); var foundIds = await context.GetContentIdsAsync(contentIds.ToHashSet());
var foundIds = await context.GetContentIdsAsync(schemaId, filter);
foreach (var id in contentIds) foreach (var id in contentIds)
{ {
if (!foundIds.Contains(id)) var (schemaId, _) = foundIds.FirstOrDefault(x => x.Id == id);
if (schemaId == Guid.Empty)
{ {
addError(context.Path, $"Contains invalid reference '{id}'."); addError(context.Path, $"Contains invalid reference '{id}'.");
} }
else if (schemaIds?.Any() == true && !schemaIds.Contains(schemaId))
{
addError(context.Path, $"Contains reference '{id}' to invalid schema.");
}
} }
} }
} }

2
src/Squidex.Domain.Apps.Core.Operations/ValidateContent/Validators/UniqueValidator.cs

@ -35,7 +35,7 @@ namespace Squidex.Domain.Apps.Core.ValidateContent.Validators
{ {
var found = await context.GetContentIdsAsync(context.SchemaId, filter); var found = await context.GetContentIdsAsync(context.SchemaId, filter);
if (found.Any(x => x != context.ContentId)) if (found.Any(x => x.Id != context.ContentId))
{ {
addError(context.Path, "Another content with the same value exists."); addError(context.Path, "Another content with the same value exists.");
} }

1
src/Squidex.Domain.Users/UserManagerExtensions.cs

@ -6,6 +6,7 @@
// ========================================================================== // ==========================================================================
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Security.Claims; using System.Security.Claims;

2
tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/NumberFieldTests.cs

@ -98,7 +98,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
{ {
var sut = Field(new NumberFieldProperties { IsUnique = true }); var sut = Field(new NumberFieldProperties { IsUnique = true });
await sut.ValidateAsync(CreateValue(12.5), errors, ValidationTestExtensions.References(Guid.NewGuid())); await sut.ValidateAsync(CreateValue(12.5), errors, ValidationTestExtensions.References((Guid.NewGuid(), Guid.NewGuid())));
errors.Should().BeEquivalentTo( errors.Should().BeEquivalentTo(
new[] { "Another content with the same value exists." }); new[] { "Another content with the same value exists." });

51
tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/ReferencesFieldTests.cs

@ -11,6 +11,7 @@ using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using FluentAssertions; using FluentAssertions;
using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Domain.Apps.Core.ValidateContent;
using Squidex.Infrastructure.Json.Objects; using Squidex.Infrastructure.Json.Objects;
using Xunit; using Xunit;
@ -36,7 +37,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
{ {
var sut = Field(new ReferencesFieldProperties()); var sut = Field(new ReferencesFieldProperties());
await sut.ValidateAsync(CreateValue(ref1), errors, ValidationTestExtensions.References(ref1)); await sut.ValidateAsync(CreateValue(ref1), errors, Context());
Assert.Empty(errors); Assert.Empty(errors);
} }
@ -46,7 +47,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
{ {
var sut = Field(new ReferencesFieldProperties()); var sut = Field(new ReferencesFieldProperties());
await sut.ValidateAsync(CreateValue(null), errors); await sut.ValidateAsync(CreateValue(null), errors, Context());
Assert.Empty(errors); Assert.Empty(errors);
} }
@ -56,7 +57,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
{ {
var sut = Field(new ReferencesFieldProperties { MinItems = 2, MaxItems = 2 }); var sut = Field(new ReferencesFieldProperties { MinItems = 2, MaxItems = 2 });
await sut.ValidateAsync(CreateValue(ref1, ref2), errors); await sut.ValidateAsync(CreateValue(ref1, ref2), errors, Context());
Assert.Empty(errors); Assert.Empty(errors);
} }
@ -66,7 +67,17 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
{ {
var sut = Field(new ReferencesFieldProperties { MinItems = 2, MaxItems = 2, AllowDuplicates = true }); var sut = Field(new ReferencesFieldProperties { MinItems = 2, MaxItems = 2, AllowDuplicates = true });
await sut.ValidateAsync(CreateValue(ref1, ref1), errors); await sut.ValidateAsync(CreateValue(ref1, ref1), errors, Context());
Assert.Empty(errors);
}
[Fact]
public async Task Should_not_add_error_if_schemas_not_defined()
{
var sut = Field(new ReferencesFieldProperties());
await sut.ValidateAsync(CreateValue(ref1), errors, ValidationTestExtensions.References((Guid.NewGuid(), ref1)));
Assert.Empty(errors); Assert.Empty(errors);
} }
@ -76,7 +87,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
{ {
var sut = Field(new ReferencesFieldProperties { SchemaId = schemaId, IsRequired = true }); var sut = Field(new ReferencesFieldProperties { SchemaId = schemaId, IsRequired = true });
await sut.ValidateAsync(CreateValue(null), errors); await sut.ValidateAsync(CreateValue(null), errors, Context());
errors.Should().BeEquivalentTo( errors.Should().BeEquivalentTo(
new[] { "Field is required." }); new[] { "Field is required." });
@ -87,7 +98,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
{ {
var sut = Field(new ReferencesFieldProperties { SchemaId = schemaId, IsRequired = true }); var sut = Field(new ReferencesFieldProperties { SchemaId = schemaId, IsRequired = true });
await sut.ValidateAsync(CreateValue(), errors); await sut.ValidateAsync(CreateValue(), errors, Context());
errors.Should().BeEquivalentTo( errors.Should().BeEquivalentTo(
new[] { "Field is required." }); new[] { "Field is required." });
@ -98,7 +109,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
{ {
var sut = Field(new ReferencesFieldProperties()); var sut = Field(new ReferencesFieldProperties());
await sut.ValidateAsync(JsonValue.Create("invalid"), errors); await sut.ValidateAsync(JsonValue.Create("invalid"), errors, Context());
errors.Should().BeEquivalentTo( errors.Should().BeEquivalentTo(
new[] { "Not a valid value." }); new[] { "Not a valid value." });
@ -109,7 +120,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
{ {
var sut = Field(new ReferencesFieldProperties { SchemaId = schemaId, MinItems = 3 }); var sut = Field(new ReferencesFieldProperties { SchemaId = schemaId, MinItems = 3 });
await sut.ValidateAsync(CreateValue(ref1, ref2), errors, ValidationTestExtensions.References(ref1, ref2)); await sut.ValidateAsync(CreateValue(ref1, ref2), errors, Context());
errors.Should().BeEquivalentTo( errors.Should().BeEquivalentTo(
new[] { "Must have at least 3 item(s)." }); new[] { "Must have at least 3 item(s)." });
@ -120,7 +131,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
{ {
var sut = Field(new ReferencesFieldProperties { SchemaId = schemaId, MaxItems = 1 }); var sut = Field(new ReferencesFieldProperties { SchemaId = schemaId, MaxItems = 1 });
await sut.ValidateAsync(CreateValue(ref1, ref2), errors, ValidationTestExtensions.References(ref1, ref2)); await sut.ValidateAsync(CreateValue(ref1, ref2), errors, Context());
errors.Should().BeEquivalentTo( errors.Should().BeEquivalentTo(
new[] { "Must not have more than 1 item(s)." }); new[] { "Must not have more than 1 item(s)." });
@ -137,12 +148,25 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
new[] { $"Contains invalid reference '{ref1}'." }); new[] { $"Contains invalid reference '{ref1}'." });
} }
[Fact]
public async Task Should_add_error_if_reference_schema_is_not_valid()
{
var sut = Field(new ReferencesFieldProperties { SchemaId = schemaId });
await sut.ValidateAsync(CreateValue(ref1), errors, ValidationTestExtensions.References((Guid.NewGuid(), ref1)));
errors.Should().BeEquivalentTo(
new[] { $"Contains reference '{ref1}' to invalid schema." });
}
[Fact] [Fact]
public async Task Should_add_error_if_reference_contains_duplicate_values() public async Task Should_add_error_if_reference_contains_duplicate_values()
{ {
var sut = Field(new ReferencesFieldProperties { SchemaId = schemaId }); var sut = Field(new ReferencesFieldProperties { SchemaId = schemaId });
await sut.ValidateAsync(CreateValue(ref1, ref1), errors, ValidationTestExtensions.References(ref1)); await sut.ValidateAsync(CreateValue(ref1, ref1), errors,
ValidationTestExtensions.References(
(schemaId, ref1)));
errors.Should().BeEquivalentTo( errors.Should().BeEquivalentTo(
new[] { "Must not contain duplicate values." }); new[] { "Must not contain duplicate values." });
@ -153,6 +177,13 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
return ids == null ? JsonValue.Null : JsonValue.Array(ids.Select(x => (object)x.ToString()).ToArray()); return ids == null ? JsonValue.Null : JsonValue.Array(ids.Select(x => (object)x.ToString()).ToArray());
} }
private ValidationContext Context()
{
return ValidationTestExtensions.References(
(schemaId, ref1),
(schemaId, ref2));
}
private static RootField<ReferencesFieldProperties> Field(ReferencesFieldProperties properties) private static RootField<ReferencesFieldProperties> Field(ReferencesFieldProperties properties)
{ {
return Fields.References(1, "my-refs", Partitioning.Invariant, properties); return Fields.References(1, "my-refs", Partitioning.Invariant, properties);

2
tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/StringFieldTests.cs

@ -120,7 +120,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
{ {
var sut = Field(new StringFieldProperties { IsUnique = true }); var sut = Field(new StringFieldProperties { IsUnique = true });
await sut.ValidateAsync(CreateValue("abc"), errors, ValidationTestExtensions.References(Guid.NewGuid())); await sut.ValidateAsync(CreateValue("abc"), errors, ValidationTestExtensions.References((Guid.NewGuid(), Guid.NewGuid())));
errors.Should().BeEquivalentTo( errors.Should().BeEquivalentTo(
new[] { "Another content with the same value exists." }); new[] { "Another content with the same value exists." });

1
tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/UIFieldTests.cs

@ -110,6 +110,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
Guid.NewGuid(), Guid.NewGuid(),
Guid.NewGuid(), Guid.NewGuid(),
(c, s) => null, (c, s) => null,
(s) => null,
(c) => null); (c) => null);
var validator = new ContentValidator(schema, x => InvariantPartitioning.Instance, validationContext); var validator = new ContentValidator(schema, x => InvariantPartitioning.Instance, validationContext);

15
tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/ValidationTestExtensions.cs

@ -17,10 +17,13 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
{ {
public static class ValidationTestExtensions public static class ValidationTestExtensions
{ {
private static readonly Task<IReadOnlyList<Guid>> EmptyReferences = Task.FromResult<IReadOnlyList<Guid>>(new List<Guid>()); private static readonly Task<IReadOnlyList<(Guid SchemaId, Guid Id)>> EmptyReferences = Task.FromResult<IReadOnlyList<(Guid SchemaId, Guid Id)>>(new List<(Guid SchemaId, Guid Id)>());
private static readonly Task<IReadOnlyList<IAssetInfo>> EmptyAssets = Task.FromResult<IReadOnlyList<IAssetInfo>>(new List<IAssetInfo>()); private static readonly Task<IReadOnlyList<IAssetInfo>> EmptyAssets = Task.FromResult<IReadOnlyList<IAssetInfo>>(new List<IAssetInfo>());
public static readonly ValidationContext ValidContext = new ValidationContext(Guid.NewGuid(), Guid.NewGuid(), (x, y) => EmptyReferences, x => EmptyAssets); public static readonly ValidationContext ValidContext = new ValidationContext(Guid.NewGuid(), Guid.NewGuid(),
(x, y) => EmptyReferences,
(x) => EmptyReferences,
(x) => EmptyAssets);
public static Task ValidateAsync(this IValidator validator, object value, IList<string> errors, ValidationContext context = null) public static Task ValidateAsync(this IValidator validator, object value, IList<string> errors, ValidationContext context = null)
{ {
@ -70,14 +73,14 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
{ {
var actual = Task.FromResult<IReadOnlyList<IAssetInfo>>(assets.ToList()); var actual = Task.FromResult<IReadOnlyList<IAssetInfo>>(assets.ToList());
return new ValidationContext(Guid.NewGuid(), Guid.NewGuid(), (x, y) => EmptyReferences, x => actual); return new ValidationContext(Guid.NewGuid(), Guid.NewGuid(), (x, y) => EmptyReferences, x => EmptyReferences, x => actual);
} }
public static ValidationContext References(params Guid[] referencesIds) public static ValidationContext References(params (Guid Id, Guid SchemaId)[] referencesIds)
{ {
var actual = Task.FromResult<IReadOnlyList<Guid>>(referencesIds.ToList()); var actual = Task.FromResult<IReadOnlyList<(Guid Id, Guid SchemaId)>>(referencesIds.ToList());
return new ValidationContext(Guid.NewGuid(), Guid.NewGuid(), (x, y) => actual, x => EmptyAssets); return new ValidationContext(Guid.NewGuid(), Guid.NewGuid(), (x, y) => actual, x => actual, x => EmptyAssets);
} }
} }
} }

6
tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/Validators/UniqueValidatorTests.cs

@ -82,7 +82,11 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent.Validators
{ {
filter(filterNode.ToString()); filter(filterNode.ToString());
return Task.FromResult<IReadOnlyList<Guid>>(new List<Guid> { id }); return Task.FromResult<IReadOnlyList<(Guid, Guid)>>(new List<(Guid, Guid)> { (schemaId, id) });
},
(ids) =>
{
return Task.FromResult<IReadOnlyList<(Guid, Guid)>>(new List<(Guid, Guid)> { (schemaId, id) });
}, },
ids => ids =>
{ {

1
tests/Squidex.Domain.Apps.Core.Tests/Squidex.Domain.Apps.Core.Tests.csproj

@ -9,7 +9,6 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\src\Squidex.Domain.Apps.Core.Model\Squidex.Domain.Apps.Core.Model.csproj" /> <ProjectReference Include="..\..\src\Squidex.Domain.Apps.Core.Model\Squidex.Domain.Apps.Core.Model.csproj" />
<ProjectReference Include="..\..\src\Squidex.Domain.Apps.Core.Operations\Squidex.Domain.Apps.Core.Operations.csproj" /> <ProjectReference Include="..\..\src\Squidex.Domain.Apps.Core.Operations\Squidex.Domain.Apps.Core.Operations.csproj" />
<ProjectReference Include="..\..\src\Squidex.Domain.Apps.Entities\Squidex.Domain.Apps.Entities.csproj" />
<ProjectReference Include="..\..\src\Squidex.Infrastructure\Squidex.Infrastructure.csproj" /> <ProjectReference Include="..\..\src\Squidex.Infrastructure\Squidex.Infrastructure.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

11
tests/Squidex.Domain.Apps.Core.Tests/TestUtils.cs

@ -129,7 +129,14 @@ namespace Squidex.Domain.Apps.Core
public static void TestFreeze(IFreezable sut) public static void TestFreeze(IFreezable sut)
{ {
foreach (var property in sut.GetType().GetRuntimeProperties().Where(x => x.Name != "IsFrozen")) var properties =
sut.GetType().GetRuntimeProperties()
.Where(x =>
x.CanWrite &&
x.CanRead &&
x.Name != "IsFrozen");
foreach (var property in properties)
{ {
var value = var value =
property.PropertyType.IsValueType ? property.PropertyType.IsValueType ?
@ -145,7 +152,7 @@ namespace Squidex.Domain.Apps.Core
sut.Freeze(); sut.Freeze();
foreach (var property in sut.GetType().GetRuntimeProperties().Where(x => x.Name != "IsFrozen")) foreach (var property in properties)
{ {
var value = var value =
property.PropertyType.IsValueType ? property.PropertyType.IsValueType ?

Loading…
Cancel
Save