mirror of https://github.com/Squidex/squidex.git
42 changed files with 1104 additions and 174 deletions
@ -0,0 +1,18 @@ |
|||
// ==========================================================================
|
|||
// IValidator.cs
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex Group
|
|||
// All rights reserved.
|
|||
// ==========================================================================
|
|||
|
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Squidex.Core.Schemas |
|||
{ |
|||
public interface IValidator |
|||
{ |
|||
Task ValidateAsync(object value, ICollection<string> errors); |
|||
} |
|||
} |
|||
@ -0,0 +1,45 @@ |
|||
// ==========================================================================
|
|||
// AllowedValuesValidator.cs
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex Group
|
|||
// All rights reserved.
|
|||
// ==========================================================================
|
|||
|
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using Squidex.Infrastructure; |
|||
using Squidex.Infrastructure.Tasks; |
|||
|
|||
namespace Squidex.Core.Schemas.Validators |
|||
{ |
|||
public sealed class AllowedValuesValidator<T> : IValidator |
|||
{ |
|||
private readonly T[] allowedValues; |
|||
|
|||
public AllowedValuesValidator(params T[] allowedValues) |
|||
{ |
|||
Guard.NotNull(allowedValues, nameof(allowedValues)); |
|||
|
|||
this.allowedValues = allowedValues; |
|||
} |
|||
|
|||
public Task ValidateAsync(object value, ICollection<string> errors) |
|||
{ |
|||
if (value == null) |
|||
{ |
|||
return TaskHelper.Done; |
|||
} |
|||
|
|||
var typedValue = (T)value; |
|||
|
|||
if (!allowedValues.Contains(typedValue)) |
|||
{ |
|||
errors.Add("<FIELD> is not an allowed value"); |
|||
} |
|||
|
|||
return TaskHelper.Done; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,54 @@ |
|||
// ==========================================================================
|
|||
// RangeValidator.cs
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex Group
|
|||
// All rights reserved.
|
|||
// ==========================================================================
|
|||
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using Squidex.Infrastructure.Tasks; |
|||
|
|||
namespace Squidex.Core.Schemas.Validators |
|||
{ |
|||
public sealed class RangeValidator<T> : IValidator where T : struct, IComparable<T> |
|||
{ |
|||
private readonly T? min; |
|||
private readonly T? max; |
|||
|
|||
public RangeValidator(T? min, T? max) |
|||
{ |
|||
if (min.HasValue && max.HasValue && min.Value.CompareTo(max.Value) >= 0) |
|||
{ |
|||
throw new ArgumentException("MinValue must larger than max value"); |
|||
} |
|||
|
|||
this.min = min; |
|||
this.max = max; |
|||
} |
|||
|
|||
public Task ValidateAsync(object value, ICollection<string> errors) |
|||
{ |
|||
if (value == null) |
|||
{ |
|||
return TaskHelper.Done; |
|||
} |
|||
|
|||
var typedValue = (T)value; |
|||
|
|||
if (min.HasValue && typedValue.CompareTo(min.Value) < 0) |
|||
{ |
|||
errors.Add($"<FIELD> must be greater than {min}"); |
|||
} |
|||
|
|||
if (max.HasValue && typedValue.CompareTo(max.Value) > 0) |
|||
{ |
|||
errors.Add($"<FIELD> must be greater than {min}"); |
|||
} |
|||
|
|||
return TaskHelper.Done; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,41 @@ |
|||
// ==========================================================================
|
|||
// RequiredStringValidator.cs
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex Group
|
|||
// All rights reserved.
|
|||
// ==========================================================================
|
|||
|
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using Squidex.Infrastructure.Tasks; |
|||
|
|||
namespace Squidex.Core.Schemas.Validators |
|||
{ |
|||
public class RequiredStringValidator : IValidator |
|||
{ |
|||
private readonly bool validateEmptyStrings; |
|||
|
|||
public RequiredStringValidator(bool validateEmptyStrings = false) |
|||
{ |
|||
this.validateEmptyStrings = validateEmptyStrings; |
|||
} |
|||
|
|||
public Task ValidateAsync(object value, ICollection<string> errors) |
|||
{ |
|||
if (value != null && !(value is string)) |
|||
{ |
|||
return TaskHelper.Done; |
|||
} |
|||
|
|||
var valueAsString = (string) value; |
|||
|
|||
if (valueAsString == null || (validateEmptyStrings && string.IsNullOrWhiteSpace(valueAsString))) |
|||
{ |
|||
errors.Add("<FIELD> is required"); |
|||
} |
|||
|
|||
return TaskHelper.Done; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
// ==========================================================================
|
|||
// RequiredValidator.cs
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex Group
|
|||
// All rights reserved.
|
|||
// ==========================================================================
|
|||
|
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using Squidex.Infrastructure.Tasks; |
|||
|
|||
namespace Squidex.Core.Schemas.Validators |
|||
{ |
|||
public class RequiredValidator : IValidator |
|||
{ |
|||
public Task ValidateAsync(object value, ICollection<string> errors) |
|||
{ |
|||
if (value == null) |
|||
{ |
|||
errors.Add("<FIELD> is required"); |
|||
} |
|||
|
|||
return TaskHelper.Done; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,48 @@ |
|||
// ==========================================================================
|
|||
// EventWrapper.cs
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex Group
|
|||
// All rights reserved.
|
|||
// ==========================================================================
|
|||
|
|||
using System; |
|||
using EventStore.ClientAPI; |
|||
|
|||
namespace Squidex.Infrastructure.CQRS.EventStore |
|||
{ |
|||
internal sealed class EventWrapper : IReceivedEvent |
|||
{ |
|||
private readonly ResolvedEvent @event; |
|||
|
|||
public int EventNumber |
|||
{ |
|||
get { return @event.OriginalEventNumber; } |
|||
} |
|||
|
|||
public string EventType |
|||
{ |
|||
get { return @event.Event.EventType; } |
|||
} |
|||
|
|||
public byte[] Metadata |
|||
{ |
|||
get { return @event.Event.Metadata; } |
|||
} |
|||
|
|||
public byte[] Payload |
|||
{ |
|||
get { return @event.Event.Data; } |
|||
} |
|||
|
|||
public DateTime Created |
|||
{ |
|||
get { return @event.Event.Created; } |
|||
} |
|||
|
|||
public EventWrapper(ResolvedEvent @event) |
|||
{ |
|||
this.@event = @event; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,25 @@ |
|||
// ==========================================================================
|
|||
// IReceivedEvent.cs
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex Group
|
|||
// All rights reserved.
|
|||
// ==========================================================================
|
|||
|
|||
using System; |
|||
|
|||
namespace Squidex.Infrastructure.CQRS.EventStore |
|||
{ |
|||
public interface IReceivedEvent |
|||
{ |
|||
int EventNumber { get; } |
|||
|
|||
string EventType { get; } |
|||
|
|||
byte[] Metadata { get; } |
|||
|
|||
byte[] Payload { get; } |
|||
|
|||
DateTime Created { get; } |
|||
} |
|||
} |
|||
@ -0,0 +1,19 @@ |
|||
using System.Reflection; |
|||
using System.Runtime.CompilerServices; |
|||
using System.Runtime.InteropServices; |
|||
|
|||
// General Information about an assembly is controlled through the following
|
|||
// set of attributes. Change these attribute values to modify the information
|
|||
// associated with an assembly.
|
|||
[assembly: AssemblyConfiguration("")] |
|||
[assembly: AssemblyCompany("")] |
|||
[assembly: AssemblyProduct("Squidex.Core.Tests")] |
|||
[assembly: AssemblyTrademark("")] |
|||
|
|||
// Setting ComVisible to false makes the types in this assembly not visible
|
|||
// to COM components. If you need to access a type in this assembly from
|
|||
// COM, set the ComVisible attribute to true on that type.
|
|||
[assembly: ComVisible(false)] |
|||
|
|||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
|||
[assembly: Guid("fd0afd44-7a93-4f9e-b5ed-72582392e435")] |
|||
@ -0,0 +1,107 @@ |
|||
// ==========================================================================
|
|||
// NumberFieldPropertiesTests.cs
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex Group
|
|||
// All rights reserved.
|
|||
// ==========================================================================
|
|||
|
|||
using System.Collections.Generic; |
|||
using System.Collections.Immutable; |
|||
using Squidex.Core.Schemas; |
|||
using Squidex.Infrastructure; |
|||
using Xunit; |
|||
using FluentAssertions; |
|||
|
|||
namespace Squidex.Core.Tests.Schemas |
|||
{ |
|||
public class NumberFieldPropertiesTests |
|||
{ |
|||
private readonly List<ValidationError> errors = new List<ValidationError>(); |
|||
|
|||
[Fact] |
|||
public void Should_not_add_error_if_properties_are_valid() |
|||
{ |
|||
var properties = new NumberFieldProperties |
|||
{ |
|||
MinValue = 0, |
|||
MaxValue = 100, |
|||
DefaultValue = 5 |
|||
}; |
|||
|
|||
properties.Validate(errors); |
|||
|
|||
Assert.Equal(0, errors.Count); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Should_add_error_if_default_value_is_less_than_min() |
|||
{ |
|||
var properties = new NumberFieldProperties { MinValue = 10, DefaultValue = 5 }; |
|||
|
|||
properties.Validate(errors); |
|||
|
|||
errors.ShouldBeEquivalentTo( |
|||
new List<ValidationError> |
|||
{ |
|||
new ValidationError("Default value must be greater than min value.", "DefaultValue") |
|||
}); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Should_add_error_if_default_value_is_greater_than_min() |
|||
{ |
|||
var properties = new NumberFieldProperties { MaxValue = 0, DefaultValue = 5 }; |
|||
|
|||
properties.Validate(errors); |
|||
|
|||
errors.ShouldBeEquivalentTo( |
|||
new List<ValidationError> |
|||
{ |
|||
new ValidationError("Default value must be less than max value.", "DefaultValue") |
|||
}); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Should_add_error_if_min_greater_than_max() |
|||
{ |
|||
var properties = new NumberFieldProperties { MinValue = 10, MaxValue = 5 }; |
|||
|
|||
properties.Validate(errors); |
|||
|
|||
errors.ShouldBeEquivalentTo( |
|||
new List<ValidationError> |
|||
{ |
|||
new ValidationError("Max value must be greater than min value.", "MinValue", "MaxValue") |
|||
}); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Should_add_error_if_allowed_values_and_max_is_specified() |
|||
{ |
|||
var properties = new NumberFieldProperties { MaxValue = 10, AllowedValues = ImmutableList.Create<double>(4) }; |
|||
|
|||
properties.Validate(errors); |
|||
|
|||
errors.ShouldBeEquivalentTo( |
|||
new List<ValidationError> |
|||
{ |
|||
new ValidationError("Either or allowed values or range can be defined.", "AllowedValues", "MinValue", "MaxValue") |
|||
}); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Should_add_error_if_allowed_values_and_min_is_specified() |
|||
{ |
|||
var properties = new NumberFieldProperties { MinValue = 10, AllowedValues = ImmutableList.Create<double>(4) }; |
|||
|
|||
properties.Validate(errors); |
|||
|
|||
errors.ShouldBeEquivalentTo( |
|||
new List<ValidationError> |
|||
{ |
|||
new ValidationError("Either or allowed values or range can be defined.", "AllowedValues", "MinValue", "MaxValue") |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,52 @@ |
|||
// ==========================================================================
|
|||
// AllowedValuesValidatorTests.cs
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex Group
|
|||
// All rights reserved.
|
|||
// ==========================================================================
|
|||
|
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using Squidex.Core.Schemas.Validators; |
|||
using Xunit; |
|||
using FluentAssertions; |
|||
|
|||
namespace Squidex.Core.Tests.Schemas.Validators |
|||
{ |
|||
public class AllowedValuesValidatorTests |
|||
{ |
|||
private readonly List<string> errors = new List<string>(); |
|||
|
|||
[Fact] |
|||
public async Task Should_not_error_if_value_null() |
|||
{ |
|||
var sut = new AllowedValuesValidator<int>(100, 200); |
|||
|
|||
await sut.ValidateAsync(null, errors); |
|||
|
|||
Assert.Equal(0, errors.Count); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_not_error_if_value_is_allowed() |
|||
{ |
|||
var sut = new AllowedValuesValidator<int>(100, 200); |
|||
|
|||
await sut.ValidateAsync(100, errors); |
|||
|
|||
Assert.Equal(0, errors.Count); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_add_error_if_value_is_not_allowed() |
|||
{ |
|||
var sut = new AllowedValuesValidator<int>(100, 200); |
|||
|
|||
await sut.ValidateAsync(50, errors); |
|||
|
|||
errors.ShouldBeEquivalentTo( |
|||
new[] { "<FIELD> is not an allowed value" }); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,76 @@ |
|||
// ==========================================================================
|
|||
// MinMaxValidatorTests.cs
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex Group
|
|||
// All rights reserved.
|
|||
// ==========================================================================
|
|||
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using FluentAssertions; |
|||
using Squidex.Core.Schemas.Validators; |
|||
using Xunit; |
|||
|
|||
namespace Squidex.Core.Tests.Schemas.Validators |
|||
{ |
|||
public class RangeValidatorTests |
|||
{ |
|||
private readonly List<string> errors = new List<string>(); |
|||
|
|||
[Theory] |
|||
[InlineData(20, 10)] |
|||
[InlineData(10, 10)] |
|||
public void Should_throw_error_if_min_greater_than_max(int? min, int? max) |
|||
{ |
|||
Assert.Throws<ArgumentException>(() => new RangeValidator<int>(min, max)); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(null, null)] |
|||
[InlineData(1000, null)] |
|||
[InlineData(1000, 2000)] |
|||
[InlineData(null, 2000)] |
|||
public async Task Should_not_error_if_value_is_within_range(int? min, int? max) |
|||
{ |
|||
var sut = new RangeValidator<int>(min, max); |
|||
|
|||
await sut.ValidateAsync(1500, errors); |
|||
|
|||
Assert.Equal(0, errors.Count); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_not_error_if_value_null() |
|||
{ |
|||
var sut = new RangeValidator<int>(100, 200); |
|||
|
|||
await sut.ValidateAsync(null, errors); |
|||
|
|||
Assert.Equal(0, errors.Count); |
|||
} |
|||
|
|||
[Theory] |
|||
public async Task Should_add_error_if_value_is_smaller_than_min() |
|||
{ |
|||
var sut = new RangeValidator<int>(2000, null); |
|||
|
|||
await sut.ValidateAsync(1500, errors); |
|||
|
|||
errors.ShouldBeEquivalentTo( |
|||
new[] { "<FIELD> must be greater than '1500'" }); |
|||
} |
|||
|
|||
[Theory] |
|||
public async Task Should_add_error_if_value_is_greater_than_max() |
|||
{ |
|||
var sut = new RangeValidator<int>(null, 1000); |
|||
|
|||
await sut.ValidateAsync(1500, errors); |
|||
|
|||
errors.ShouldBeEquivalentTo( |
|||
new[] { "<FIELD> must be less than '1000'" }); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,67 @@ |
|||
// ==========================================================================
|
|||
// RequiredValidatorTests.cs
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex Group
|
|||
// All rights reserved.
|
|||
// ==========================================================================
|
|||
|
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using Squidex.Core.Schemas.Validators; |
|||
using Xunit; |
|||
using FluentAssertions; |
|||
|
|||
namespace Squidex.Core.Tests.Schemas.Validators |
|||
{ |
|||
public sealed class RequiredStringValidatorTests |
|||
{ |
|||
private readonly List<string> errors = new List<string>(); |
|||
|
|||
[Theory] |
|||
[InlineData("MyString")] |
|||
[InlineData("")] |
|||
[InlineData(" ")] |
|||
[InlineData(" ")] |
|||
public async Task Should_not_add_error_if_object_is_valid(string value) |
|||
{ |
|||
var sut = new RequiredStringValidator(); |
|||
|
|||
await sut.ValidateAsync(value, errors); |
|||
|
|||
Assert.Equal(0, errors.Count); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_not_add_error_if_object_is_another_type() |
|||
{ |
|||
var sut = new RequiredStringValidator(); |
|||
|
|||
await sut.ValidateAsync(true, errors); |
|||
|
|||
Assert.Equal(0, errors.Count); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_add_error_if_empty_strings_are_not_allowed() |
|||
{ |
|||
var sut = new RequiredStringValidator(true); |
|||
|
|||
await sut.ValidateAsync(string.Empty, errors); |
|||
|
|||
errors.ShouldBeEquivalentTo( |
|||
new[] { "<FIELD> is required" }); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_add_error_if_object_is_null() |
|||
{ |
|||
var sut = new RequiredStringValidator(); |
|||
|
|||
await sut.ValidateAsync(null, errors); |
|||
|
|||
errors.ShouldBeEquivalentTo( |
|||
new[] { "<FIELD> is required" }); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,52 @@ |
|||
// ==========================================================================
|
|||
// RequiredValidatorTests.cs
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex Group
|
|||
// All rights reserved.
|
|||
// ==========================================================================
|
|||
|
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using Squidex.Core.Schemas.Validators; |
|||
using Xunit; |
|||
using FluentAssertions; |
|||
|
|||
namespace Squidex.Core.Tests.Schemas.Validators |
|||
{ |
|||
public sealed class RequiredValidatorTests |
|||
{ |
|||
private readonly List<string> errors = new List<string>(); |
|||
|
|||
[Fact] |
|||
public async Task Should_not_add_error_if_object_is_valid() |
|||
{ |
|||
var sut = new RequiredValidator(); |
|||
|
|||
await sut.ValidateAsync(true, errors); |
|||
|
|||
Assert.Equal(0, errors.Count); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_not_add_error_for_empty_string() |
|||
{ |
|||
var sut = new RequiredValidator(); |
|||
|
|||
await sut.ValidateAsync(string.Empty, errors); |
|||
|
|||
Assert.Equal(0, errors.Count); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_add_error_if_object_is_null() |
|||
{ |
|||
var sut = new RequiredValidator(); |
|||
|
|||
await sut.ValidateAsync(null, errors); |
|||
|
|||
errors.ShouldBeEquivalentTo( |
|||
new[] { "<FIELD> is required" }); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,22 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
|||
<PropertyGroup> |
|||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion> |
|||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath> |
|||
</PropertyGroup> |
|||
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" /> |
|||
<PropertyGroup Label="Globals"> |
|||
<ProjectGuid>fd0afd44-7a93-4f9e-b5ed-72582392e435</ProjectGuid> |
|||
<RootNamespace>Squidex.Core.Tests</RootNamespace> |
|||
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath> |
|||
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath> |
|||
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion> |
|||
</PropertyGroup> |
|||
<PropertyGroup> |
|||
<SchemaVersion>2.0</SchemaVersion> |
|||
</PropertyGroup> |
|||
<ItemGroup> |
|||
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" /> |
|||
</ItemGroup> |
|||
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" /> |
|||
</Project> |
|||
@ -0,0 +1,35 @@ |
|||
{ |
|||
"buildOptions": { |
|||
"copyToOutput": { |
|||
"include": [ |
|||
"xunit.runner.json" |
|||
] |
|||
} |
|||
}, |
|||
"dependencies": { |
|||
"FluentAssertions": "4.15.0", |
|||
"dotnet-test-xunit": "2.2.0-preview2-build1029", |
|||
"Moq": "4.6.38-alpha", |
|||
"Squidex.Core": "1.0.0-*", |
|||
"Squidex.Infrastructure": "1.0.0-*", |
|||
"xunit": "2.2.0-beta3-build3402" |
|||
}, |
|||
"frameworks": { |
|||
"netcoreapp1.0": { |
|||
"dependencies": { |
|||
"Microsoft.NETCore.App": { |
|||
"type": "platform", |
|||
"version": "1.0.1" |
|||
} |
|||
} |
|||
} |
|||
}, |
|||
"testRunner": "xunit", |
|||
"tooling": { |
|||
"defaultNamespace": "Squidex.Core.Tests" |
|||
}, |
|||
"tools": { |
|||
"Microsoft.DotNet.Watcher.Tools": "1.0.0-preview2-final" |
|||
}, |
|||
"version": "1.0.0-*" |
|||
} |
|||
@ -0,0 +1,60 @@ |
|||
// ==========================================================================
|
|||
// EnvelopeHeaderTests.cs
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex Group
|
|||
// All rights reserved.
|
|||
// ==========================================================================
|
|||
|
|||
using System.Linq; |
|||
using Xunit; |
|||
|
|||
namespace Squidex.Infrastructure.CQRS |
|||
{ |
|||
public class EnvelopeHeaderTests |
|||
{ |
|||
[Fact] |
|||
public void Should_create_headers() |
|||
{ |
|||
var headers = new EnvelopeHeaders(); |
|||
|
|||
Assert.Equal(0, headers.Count); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Should_create_headers_with_null_properties() |
|||
{ |
|||
var headers = new EnvelopeHeaders(null); |
|||
|
|||
Assert.Equal(0, headers.Count); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Should_create_headers_as_copy() |
|||
{ |
|||
var source = new PropertiesBag().Set("Key1", 123); |
|||
var headers = new EnvelopeHeaders(source); |
|||
|
|||
CompareHeaders(headers, source); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Should_clone_headers() |
|||
{ |
|||
var source = new PropertiesBag().Set("Key1", 123); |
|||
var headers = new EnvelopeHeaders(source); |
|||
|
|||
var clone = headers.Clone(); |
|||
|
|||
CompareHeaders(headers, clone); |
|||
} |
|||
|
|||
private static void CompareHeaders(PropertiesBag lhs, PropertiesBag rhs) |
|||
{ |
|||
foreach (var key in lhs.PropertyNames.Concat(rhs.PropertyNames).Distinct()) |
|||
{ |
|||
Assert.Equal(lhs[key].ToString(), rhs[key].ToString()); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,63 @@ |
|||
// ==========================================================================
|
|||
// DefaultNameResolverTests.cs
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex Group
|
|||
// All rights reserved.
|
|||
// ==========================================================================
|
|||
|
|||
using System; |
|||
using Squidex.Infrastructure.CQRS.Events; |
|||
using Xunit; |
|||
|
|||
namespace Squidex.Infrastructure.CQRS.EventStore |
|||
{ |
|||
public class DefaultNameResolverTests |
|||
{ |
|||
private sealed class User : DomainObject |
|||
{ |
|||
public User(Guid id, int version) |
|||
: base(id, version) |
|||
{ |
|||
} |
|||
|
|||
protected override void DispatchEvent(Envelope<IEvent> @event) |
|||
{ |
|||
} |
|||
} |
|||
|
|||
private sealed class UserDomainObject : DomainObject |
|||
{ |
|||
public UserDomainObject(Guid id, int version) |
|||
: base(id, version) |
|||
{ |
|||
} |
|||
|
|||
protected override void DispatchEvent(Envelope<IEvent> @event) |
|||
{ |
|||
} |
|||
} |
|||
|
|||
[Fact] |
|||
public void Should_calculate_name() |
|||
{ |
|||
var sut = new DefaultNameResolver("Squidex"); |
|||
var user = new User(Guid.NewGuid(), 1); |
|||
|
|||
var name = sut.GetStreamName(typeof(User), user.Id); |
|||
|
|||
Assert.Equal($"squidex-user-{user.Id}", name); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Should_calculate_name_and_remove_suffix() |
|||
{ |
|||
var sut = new DefaultNameResolver("Squidex"); |
|||
var user = new UserDomainObject(Guid.NewGuid(), 1); |
|||
|
|||
var name = sut.GetStreamName(typeof(User), user.Id); |
|||
|
|||
Assert.Equal($"squidex-user-{user.Id}", name); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,92 @@ |
|||
// ==========================================================================
|
|||
// EventStoreFormatterTests.cs
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex Group
|
|||
// All rights reserved.
|
|||
// ==========================================================================
|
|||
|
|||
using System; |
|||
using System.Linq; |
|||
using Newtonsoft.Json; |
|||
using NodaTime; |
|||
using Squidex.Infrastructure.CQRS.Events; |
|||
using Squidex.Infrastructure.Json; |
|||
using Xunit; |
|||
|
|||
namespace Squidex.Infrastructure.CQRS.EventStore |
|||
{ |
|||
public class EventStoreFormatterTests |
|||
{ |
|||
public sealed class Event : IEvent |
|||
{ |
|||
public string MyProperty { get; set; } |
|||
} |
|||
|
|||
public sealed class ReceivedEvent : IReceivedEvent |
|||
{ |
|||
public int EventNumber { get; set; } |
|||
|
|||
public string EventType { get; set; } |
|||
|
|||
public byte[] Metadata { get; set; } |
|||
|
|||
public byte[] Payload { get; set; } |
|||
|
|||
public DateTime Created { get; set; } |
|||
} |
|||
|
|||
private static readonly JsonSerializerSettings serializerSettings = new JsonSerializerSettings(); |
|||
|
|||
static EventStoreFormatterTests() |
|||
{ |
|||
serializerSettings.Converters.Add(new PropertiesBagConverter()); |
|||
} |
|||
|
|||
public EventStoreFormatterTests() |
|||
{ |
|||
TypeNameRegistry.Map(typeof(Event), "Event"); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Should_serialize_and_deserialize_envelope() |
|||
{ |
|||
var commitId = Guid.NewGuid(); |
|||
var inputEvent = new Envelope<Event>(new Event { MyProperty = "My-Property" }); |
|||
|
|||
inputEvent.SetAggregateId(Guid.NewGuid()); |
|||
inputEvent.SetAppId(Guid.NewGuid()); |
|||
inputEvent.SetCommitId(commitId); |
|||
inputEvent.SetEventId(Guid.NewGuid()); |
|||
inputEvent.SetEventNumber(1); |
|||
inputEvent.SetTimestamp(SystemClock.Instance.GetCurrentInstant()); |
|||
|
|||
var sut = new EventStoreFormatter(serializerSettings); |
|||
|
|||
var eventData = sut.ToEventData(inputEvent.To<IEvent>(), commitId); |
|||
|
|||
var receivedEvent = new ReceivedEvent |
|||
{ |
|||
Payload = eventData.Data, |
|||
Created = inputEvent.Headers.Timestamp().ToDateTimeUtc(), |
|||
EventNumber = 1, |
|||
EventType = "event", |
|||
Metadata = eventData.Metadata |
|||
}; |
|||
|
|||
var outputEvent = sut.Parse(receivedEvent).To<Event>(); |
|||
|
|||
CompareHeaders(outputEvent.Headers, inputEvent.Headers); |
|||
|
|||
Assert.Equal(inputEvent.Payload.MyProperty, outputEvent.Payload.MyProperty); |
|||
} |
|||
|
|||
private static void CompareHeaders(PropertiesBag lhs, PropertiesBag rhs) |
|||
{ |
|||
foreach (var key in lhs.PropertyNames.Concat(rhs.PropertyNames).Distinct()) |
|||
{ |
|||
Assert.Equal(lhs[key].ToString(), rhs[key].ToString()); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,53 @@ |
|||
// ==========================================================================
|
|||
// ReflectionExtensionTests.cs
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex Group
|
|||
// All rights reserved.
|
|||
// ==========================================================================
|
|||
|
|||
using System.Linq; |
|||
using Xunit; |
|||
// ReSharper disable UnusedMember.Local
|
|||
|
|||
namespace Squidex.Infrastructure.Reflection |
|||
{ |
|||
public class ReflectionExtensionTests |
|||
{ |
|||
private interface IMain : ISub1 |
|||
{ |
|||
string MainProp { get; set; } |
|||
} |
|||
|
|||
private interface ISub1 : ISub2 |
|||
{ |
|||
string Sub1Prop { get; set; } |
|||
} |
|||
|
|||
private interface ISub2 |
|||
{ |
|||
string Sub2Prop { get; set; } |
|||
} |
|||
|
|||
private class Main |
|||
{ |
|||
public string MainProp { get; set; } |
|||
} |
|||
|
|||
[Fact] |
|||
public void Should_find_all_public_properties_of_interfaces() |
|||
{ |
|||
var properties = typeof(IMain).GetPublicProperties().Select(x => x.Name).OrderBy(x => x).ToArray(); |
|||
|
|||
Assert.Equal(new [] { "MainProp", "Sub1Prop", "Sub2Prop" }, properties); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Should_find_all_public_properties_of_classes() |
|||
{ |
|||
var properties = typeof(Main).GetPublicProperties().Select(x => x.Name).OrderBy(x => x).ToArray(); |
|||
|
|||
Assert.Equal(new[] { "MainProp" }, properties); |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue