Add DateValidationAttribute

This commit is contained in:
ngfrolov 2023-03-24 12:34:57 +05:00
parent 8c11988c92
commit b64c90b3e3
Signed by untrusted user who does not match committer: ng.frolov
GPG Key ID: E99907A0357B29A7
2 changed files with 188 additions and 0 deletions

View File

@ -0,0 +1,80 @@
using System;
using System.ComponentModel.DataAnnotations;
namespace AsbCloudApp.ValidationAttributes
{
/// <summary>
/// Атрибут валидации даты-времени
/// </summary>
[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property)]
public class DateValidationAttribute : ValidationAttribute
{
private DateTime? gtDate;
/// <summary>
/// null разрешен
/// </summary>
public bool AllowNull { get; set; } = true;
/// <summary>
/// Разрешена только дат.
/// При наличии времени в DateTime инвалидирует.
/// При наличии UTC тоже инвалидирует.
/// </summary>
public bool IsDateOnly { get; set; } = false;
/// <summary>
/// Допустима дата-время в UTC
/// </summary>
public bool AllowUtc { get; set; } = true;
/// <summary>
/// Дата больше которой должно быть проверяемое значение.
/// Формат строки - любой поддерживаемый DateTime.Parse.
/// Желательно использовать ISO 8601 формат
/// </summary>
public string? GtDate {
get => gtDate.ToString();
set
{
if(value is null)
gtDate = null;
else
gtDate = DateTime.Parse(value);
}
}
/// <summary>
/// Проверка значения
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public override bool IsValid(object? value)
{
if (value is null)
return AllowNull;
if (value is not DateTime dateTime)
return false;
if (IsDateOnly)
{
if (dateTime.Hour > 0 ||
dateTime.Minute > 0 ||
dateTime.Second > 0 ||
dateTime.Millisecond > 0 ||
dateTime.Kind == DateTimeKind.Utc)
return false;
}
if (!AllowUtc && dateTime.Kind == DateTimeKind.Utc)
return false;
if (gtDate.HasValue && dateTime <= gtDate)
return false;
return true;
}
}
}

View File

@ -0,0 +1,108 @@
using AsbCloudApp.ValidationAttributes;
using System;
using Xunit;
namespace AsbCloudWebApi.Tests.AttributeTest
{
public class DateValidationAttributeTest
{
[Fact]
public void AllowNull_true_on_null_valid()
{
var attribute = new DateValidationAttribute { AllowNull = true };
var result = attribute.IsValid(null);
Assert.True(result);
}
[Fact]
public void AllowNull_false_on_null_invalid()
{
var attribute = new DateValidationAttribute { AllowNull = false };
var result = attribute.IsValid(null);
Assert.False(result);
}
[Fact]
public void IsDateOnly_true_on_empty_timePart_valid()
{
var attribute = new DateValidationAttribute { IsDateOnly = true };
var date = new DateTime(2023, 01, 01, 00, 00, 00);
var result = attribute.IsValid(date);
Assert.True(result);
}
[Fact]
public void IsDateOnly_true_on_timePart_invalid()
{
var attribute = new DateValidationAttribute { IsDateOnly = true };
var date = new DateTime(2023, 01, 01, 01, 01, 01);
var result = attribute.IsValid(date);
Assert.False(result);
}
[Fact]
public void IsDateOnly_true_on_utc_invalid()
{
var attribute = new DateValidationAttribute { IsDateOnly = true };
var date = new DateTime(2023, 01, 01, 00, 00, 00, DateTimeKind.Utc);
var result = attribute.IsValid(date);
Assert.False(result);
}
[Fact]
public void AllowUtc_true_on_unspecified_valid()
{
var attribute = new DateValidationAttribute { AllowUtc = true };
var date = new DateTime(2023, 01, 01, 00, 00, 00, DateTimeKind.Unspecified);
var result = attribute.IsValid(date);
Assert.True(result);
}
[Fact]
public void AllowUtc_true_on_utc_valid()
{
var attribute = new DateValidationAttribute { AllowUtc = true };
var date = new DateTime(2023, 01, 01, 00, 00, 00, DateTimeKind.Utc);
var result = attribute.IsValid(date);
Assert.True(result);
}
[Fact]
public void AllowUtc_false_on_utc_invalid()
{
var attribute = new DateValidationAttribute { AllowUtc = false };
var date = new DateTime(2023, 01, 01, 00, 00, 00, DateTimeKind.Utc);
var result = attribute.IsValid(date);
Assert.False(result);
}
[Fact]
public void AllowUtc_false_on_unspecified_valid()
{
var attribute = new DateValidationAttribute { AllowUtc = false };
var date = new DateTime(2023, 01, 01, 00, 00, 00, DateTimeKind.Unspecified);
var result = attribute.IsValid(date);
Assert.True(result);
}
[Fact]
public void GtDate_on_same_date_invalid()
{
var gtDate = "2023-01-01T00:00:00";
var date = DateTime.Parse(gtDate);
var attribute = new DateValidationAttribute { GtDate = gtDate };
var result = attribute.IsValid(date);
Assert.False(result);
}
[Fact]
public void GtDate_on_greater_date_valid()
{
var gtDate = "2023-01-01T00:00:00";
var date = DateTime.Parse(gtDate).AddMilliseconds(1);
var attribute = new DateValidationAttribute { GtDate = gtDate };
var result = attribute.IsValid(date);
Assert.True(result);
}
}
}