Коммит 6babf3cd создал по автору Evgeniy Zyatyna's avatar Evgeniy Zyatyna
Просмотр файлов

Merge branch 'develop' into 'master'

️ Реализована модификация RequiredAttribute для DatePostViewModel.

See merge request smon.monq.ru/libraries/Monq.Models.Abstractions!9
владельцы 2925a790 b1d2cd40
variables:
CUSTOM_TEMPLATE: "true"
image: mcr.microsoft.com/dotnet/core/sdk:3.0
test_image:
stage: test
script:
- color_print INFORMATION "Skip stage"
except:
- tags
dependencies:
- build_project
image: mcr.microsoft.com/dotnet/core/sdk:3.1
include:
- project: 'smon.monq.ru/devops/devops-files'
......
......@@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29123.88
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Monq.Models.Abstractions", "src\Monq.Models.Abstractions\Monq.Models.Abstractions.csproj", "{DCCC9998-4058-420A-B735-06603BE95640}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Monq.Models.Abstractions", "src\Monq.Models.Abstractions\Monq.Models.Abstractions.csproj", "{DCCC9998-4058-420A-B735-06603BE95640}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{9B151E16-E04D-4AF1-8838-D62FA8C15442}"
ProjectSection(SolutionItems) = preProject
......@@ -15,6 +15,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{FAA517DE-B63C-452A-9F46-067CE757FBE0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Monq.Models.Abstractions.Tests", "src\Monq.Models.Abstractions.Tests\Monq.Models.Abstractions.Tests.csproj", "{FB342C02-E7A4-4C8D-884F-336620457B98}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
......@@ -25,12 +27,17 @@ Global
{DCCC9998-4058-420A-B735-06603BE95640}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DCCC9998-4058-420A-B735-06603BE95640}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DCCC9998-4058-420A-B735-06603BE95640}.Release|Any CPU.Build.0 = Release|Any CPU
{FB342C02-E7A4-4C8D-884F-336620457B98}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FB342C02-E7A4-4C8D-884F-336620457B98}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FB342C02-E7A4-4C8D-884F-336620457B98}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FB342C02-E7A4-4C8D-884F-336620457B98}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{DCCC9998-4058-420A-B735-06603BE95640} = {FAA517DE-B63C-452A-9F46-067CE757FBE0}
{FB342C02-E7A4-4C8D-884F-336620457B98} = {FAA517DE-B63C-452A-9F46-067CE757FBE0}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {3FB67764-8482-4C21-AE9F-8BEDC908C8BB}
......
......@@ -188,4 +188,30 @@ public class GateAutomatonRulePutViewModel
[NotEmpty(ErrorMessage = "Не указан список входных переменных скрипта правила.")]
public IEnumerable<GateAutomatonRuleVariablePostViewModel> Variables { get; set; } = Enumerable.Empty<GateAutomatonRuleVariablePostViewModel>();
}
```
#### V. DateRequiredAttribute
> Модификация _RequiredAttribute_ для типа _DateRangePostViewModel_.
##### Пример:
```CSharp
/// <summary>
/// Принимаемая модель фильтра истории действий синтетического триггера.
/// </summary>
public class GateSTEventHistoryFilterViewModel
{
/// <summary>
/// Дата регистрации события (UnixTimeStamp).
/// </summary>
[DateRequired(ErrorMessage = "Не указана дата начала события.")]
public DatePostViewModel DateStart { get; set; } = null;
/// <summary>
/// Дата окончания события (UnixTimeStamp).
/// </summary>
[DateRequired(ErrorMessage = "Не указана дата окончания события.")]
public DatePostViewModel DateEnd { get; set; } = null;
}
```
\ Нет новой строки в конце файла
using Xunit;
using System;
using System.Collections.Generic;
using Monq.Models.Abstractions.DataAnnotations;
namespace Monq.Models.Abstractions.Tests
{
public class DateRequiredAttributeTests
{
[Theory(DisplayName = "Проверка валидации DatePostViewModel - простые поля.")]
[MemberData(nameof(ShouldProperlyValidateDateModelWithSimpleValueData))]
public void ShouldProperlyValidateDateModelWithSimpleValue(DatePostViewModel model)
{
var attribute = new DateRequiredAttribute();
var result = attribute.IsValid(model);
Assert.True(result);
}
[Fact(DisplayName = "Проверка валидации DatePostViewModel - диапазон дат.")]
public void ShouldProperlyValidateDateModelWithRange()
{
var attribute = new DateRequiredAttribute();
var model = new DatePostViewModel
{
Range = new DateRangePostViewModel
{
Start = DateTimeOffset.Now.AddDays(-2).ToUnixTimeSeconds(),
End = DateTimeOffset.Now.ToUnixTimeSeconds()
}
};
var result = attribute.IsValid(model);
Assert.True(result);
}
[Fact(DisplayName = "Проверка валидации DatePostViewModel - пустая модель.")]
public void ShouldProperlyValidateEmptyModel()
{
var attribute = new DateRequiredAttribute();
var model = new DatePostViewModel();
var result = attribute.IsValid(model);
Assert.False(result);
}
[Fact(DisplayName = "Проверка валидации DatePostViewModel - не указаны все поля в диапазоне.",
Skip = "Следует сделать nullable поля в DateRangePostViewModel и обновить другие библиотеки, где это используется.")]
public void ShouldProperlyValidateWrongRangeModel()
{
var attribute = new DateRequiredAttribute();
var model = new DatePostViewModel
{
Range = new DateRangePostViewModel
{
Start = DateTimeOffset.Now.AddDays(-2).ToUnixTimeSeconds()
}
};
var result = attribute.IsValid(model);
Assert.False(result);
}
static IEnumerable<object[]> ShouldProperlyValidateDateModelWithSimpleValueData() =>
new[]
{
new[]
{
new DatePostViewModel { Equal = DateTimeOffset.Now.ToUnixTimeSeconds() }
},
new[]
{
new DatePostViewModel { LessThan = DateTimeOffset.Now.ToUnixTimeSeconds() }
},
new[]
{
new DatePostViewModel { LessThanOrEqual = DateTimeOffset.Now.ToUnixTimeSeconds() }
},
new[]
{
new DatePostViewModel { MoreThan = DateTimeOffset.Now.ToUnixTimeSeconds() }
},
new[]
{
new DatePostViewModel { MoreThanOrEqual = DateTimeOffset.Now.ToUnixTimeSeconds() }
},
};
}
}
\ Нет новой строки в конце файла
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
<PackageReference Include="Monq.Tools.TestExtensions" Version="2.0.0-build-101878" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Monq.Models.Abstractions\Monq.Models.Abstractions.csproj" />
</ItemGroup>
</Project>
......@@ -6,7 +6,6 @@ namespace Monq.Models.Abstractions.DataAnnotations
/// <summary>
/// Модификация <see cref="RequiredAttribute"/> для типа <see cref="BasicIdPostViewModel"/>.
/// </summary>
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter)]
public sealed class BasicIdRequiredAttribute : RequiredAttribute
{
......@@ -18,6 +17,5 @@ namespace Monq.Models.Abstractions.DataAnnotations
else
return false;
}
}
}
\ Нет новой строки в конце файла
using System;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Reflection;
namespace Monq.Models.Abstractions.DataAnnotations
{
/// <summary>
/// Модификация <see cref="RequiredAttribute"/> для типа <see cref="DatePostViewModel"/>.
/// </summary>
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter)]
public class DateRequiredAttribute : RequiredAttribute
{
/// <inheritdoc />
public override bool IsValid(object value)
{
if (value != null && value is DatePostViewModel dateModel)
{
if (dateModel.Range != null && !dateModel.Equal.HasValue)
{
var nestedPropsToValidate = typeof(DateRangePostViewModel)
.GetProperties(BindingFlags.Instance | BindingFlags.Public)
.Where(p => p.IsDefined(typeof(ValidationAttribute)));
foreach (var property in nestedPropsToValidate)
{
var validators = GetCustomAttributes(property, typeof(ValidationAttribute)) as ValidationAttribute[];
if (validators == null || validators.Length == 0)
continue;
var propValue = property.GetValue(dateModel.Range);
foreach (var validator in validators)
{
var result = validator.GetValidationResult(propValue, new ValidationContext(dateModel.Range));
if (result == null || result == ValidationResult.Success)
continue;
return false;
}
}
return true;
}
return dateModel.Equal.HasValue ||
dateModel.LessThan.HasValue ||
dateModel.LessThanOrEqual.HasValue ||
dateModel.MoreThan.HasValue ||
dateModel.MoreThanOrEqual.HasValue;
}
else
return false;
}
}
}
\ Нет новой строки в конце файла
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Version>3.1.0</Version>
<Version>3.2.0</Version>
<VersionSuffix>$(VersionSuffix)</VersionSuffix>
<Version Condition=" '$(VersionSuffix)' != '' ">$(Version)-$(VersionSuffix)</Version>
<TargetFramework>netstandard2.0</TargetFramework>
......
Поддерживает Markdown
0% или .
You are about to add 0 people to the discussion. Proceed with caution.
Сначала завершите редактирование этого сообщения!
Пожалуйста, зарегистрируйтесь или чтобы прокомментировать