diff options
author | 杨宇千 <crupest@outlook.com> | 2019-08-21 23:55:42 +0800 |
---|---|---|
committer | 杨宇千 <crupest@outlook.com> | 2019-08-21 23:55:42 +0800 |
commit | 1a998040268282086549e67ae81f8e059ee885a9 (patch) | |
tree | 7797613e18dd50665ac50881541f645413dbca97 | |
parent | 431ba02aa831448ca2aa9e9a42aa3aaf1345edbe (diff) | |
download | timeline-1a998040268282086549e67ae81f8e059ee885a9.tar.gz timeline-1a998040268282086549e67ae81f8e059ee885a9.tar.bz2 timeline-1a998040268282086549e67ae81f8e059ee885a9.zip |
Add validators.
-rw-r--r-- | Timeline.Tests/UserDetailValidatorTest.cs | 97 | ||||
-rw-r--r-- | Timeline.Tests/UsernameValidatorUnitTest.cs | 1 | ||||
-rw-r--r-- | Timeline/Entities/UserDetail.cs | 2 | ||||
-rw-r--r-- | Timeline/Models/UserDetail.cs | 7 | ||||
-rw-r--r-- | Timeline/Models/Validation/UserDetailValidator.cs | 113 |
5 files changed, 214 insertions, 6 deletions
diff --git a/Timeline.Tests/UserDetailValidatorTest.cs b/Timeline.Tests/UserDetailValidatorTest.cs new file mode 100644 index 00000000..9b112946 --- /dev/null +++ b/Timeline.Tests/UserDetailValidatorTest.cs @@ -0,0 +1,97 @@ +using FluentAssertions;
+using System.Collections.Generic;
+using Timeline.Models.Validation;
+using Xunit;
+
+namespace Timeline.Tests
+{
+ public static class UserDetailValidatorsTest
+ {
+ private static void SucceedWith<TValidator>(object value) where TValidator : class, IValidator, new()
+ {
+ var result = new TValidator().Validate(value, out var message);
+ result.Should().BeTrue();
+ message.Should().Equals(ValidationConstants.SuccessMessage);
+ }
+
+ private static void FailWith<TValidator>(object value, params string[] messageContains) where TValidator : class, IValidator, new()
+ {
+ var result = new TValidator().Validate(value, out var message);
+ result.Should().BeFalse();
+
+ foreach (var m in messageContains)
+ {
+ message.Should().ContainEquivalentOf(m);
+ }
+ }
+
+ public class QQ
+ {
+ [Theory]
+ [InlineData(null)]
+ [InlineData("")]
+ [InlineData("12345678")]
+ public void Success(object qq)
+ {
+ SucceedWith<UserDetailValidators.QQValidator>(qq);
+ }
+
+ [Theory]
+ [InlineData(123, "type")]
+ [InlineData("123", "short")]
+ [InlineData("111111111111111111111111111111111111", "long")]
+ [InlineData("aaaaaaaa", "digit")]
+ public void Fail(object qq, string messageContains)
+ {
+ FailWith<UserDetailValidators.QQValidator>(qq, messageContains);
+ }
+ }
+
+ public class EMail
+ {
+ [Theory]
+ [InlineData(null)]
+ [InlineData("")]
+ [InlineData("aaa@aaa.net")]
+ public void Success(object email)
+ {
+ SucceedWith<UserDetailValidators.EMailValidator>(email);
+ }
+
+ public static IEnumerable<object[]> FailTestData()
+ {
+ yield return new object[] { 123, "type" };
+ yield return new object[] { new string('a', 100), "long" };
+ yield return new object[] { "aaaaaaaa", "format" };
+ }
+
+ [Theory]
+ [MemberData(nameof(FailTestData))]
+ public void Fail(object email, string messageContains)
+ {
+ FailWith<UserDetailValidators.EMailValidator>(email, messageContains);
+ }
+ }
+
+ public class PhoneNumber
+ {
+ [Theory]
+ [InlineData(null)]
+ [InlineData("")]
+ [InlineData("12345678910")]
+ public void Success(object phoneNumber)
+ {
+ SucceedWith<UserDetailValidators.PhoneNumberValidator>(phoneNumber);
+ }
+
+ [Theory]
+ [InlineData(123, "type")]
+ [InlineData("111111111111111111111111111111111111", "long")]
+ [InlineData("aaaaaaaa", "digit")]
+ public void Fail(object phoneNumber, string messageContains)
+ {
+ FailWith<UserDetailValidators.PhoneNumberValidator>(phoneNumber, messageContains);
+ }
+ }
+ }
+}
diff --git a/Timeline.Tests/UsernameValidatorUnitTest.cs b/Timeline.Tests/UsernameValidatorUnitTest.cs index 20558d0e..6a635ba1 100644 --- a/Timeline.Tests/UsernameValidatorUnitTest.cs +++ b/Timeline.Tests/UsernameValidatorUnitTest.cs @@ -1,5 +1,4 @@ using FluentAssertions;
-using System;
using Timeline.Models.Validation;
using Xunit;
diff --git a/Timeline/Entities/UserDetail.cs b/Timeline/Entities/UserDetail.cs index ee829717..9bc6f5e5 100644 --- a/Timeline/Entities/UserDetail.cs +++ b/Timeline/Entities/UserDetail.cs @@ -12,7 +12,7 @@ namespace Timeline.Entities [Column("qq"), MaxLength(15)]
public string QQ { get; set; }
- [Column("email"), MaxLength(30)]
+ [Column("email"), MaxLength(50)]
public string EMail { get; set; }
[Column("phone_number"), MaxLength(15)]
diff --git a/Timeline/Models/UserDetail.cs b/Timeline/Models/UserDetail.cs index 91439c6a..4af88450 100644 --- a/Timeline/Models/UserDetail.cs +++ b/Timeline/Models/UserDetail.cs @@ -1,12 +1,19 @@ using Timeline.Entities;
+using Timeline.Models.Validation;
namespace Timeline.Models
{
public class UserDetail
{
+ [ValidateWith(typeof(UserDetailValidators.QQValidator))]
public string QQ { get; set; }
+
+ [ValidateWith(typeof(UserDetailValidators.EMailValidator))]
public string EMail { get; set; }
+
+ [ValidateWith(typeof(UserDetailValidators.PhoneNumberValidator))]
public string PhoneNumber { get; set; }
+
public string Description { get; set; }
private static string CoerceEmptyToNull(string value)
diff --git a/Timeline/Models/Validation/UserDetailValidator.cs b/Timeline/Models/Validation/UserDetailValidator.cs index 5fdaec00..19c82edb 100644 --- a/Timeline/Models/Validation/UserDetailValidator.cs +++ b/Timeline/Models/Validation/UserDetailValidator.cs @@ -1,11 +1,116 @@ using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
+using System.Net.Mail;
namespace Timeline.Models.Validation
{
- public class UserDetailValidator
+ public abstract class OptionalStringValidator : IValidator
{
+ public bool Validate(object value, out string message)
+ {
+ if (value == null)
+ {
+ message = ValidationConstants.SuccessMessage;
+ return true;
+ }
+
+ if (value is string s)
+ {
+ if (s.Length == 0)
+ {
+ message = ValidationConstants.SuccessMessage;
+ return true;
+ }
+ return DoValidate(s, out message);
+ }
+ else
+ {
+ message = "Value is not of type string.";
+ return false;
+ }
+ }
+
+ protected abstract bool DoValidate(string value, out string message);
+ }
+
+ public static class UserDetailValidators
+ {
+
+ public class QQValidator : OptionalStringValidator
+ {
+ protected override bool DoValidate(string value, out string message)
+ {
+ if (value.Length < 5)
+ {
+ message = "QQ is too short.";
+ return false;
+ }
+
+ if (value.Length > 11)
+ {
+ message = "QQ is too long.";
+ return false;
+ }
+
+ foreach (var c in value)
+ {
+ if (!char.IsDigit(c))
+ {
+ message = "QQ must only contain digit.";
+ return false;
+ }
+ }
+
+ message = ValidationConstants.SuccessMessage;
+ return true;
+ }
+ }
+
+ public class EMailValidator : OptionalStringValidator
+ {
+ protected override bool DoValidate(string value, out string message)
+ {
+ if (value.Length > 50)
+ {
+ message = "E-Mail is too long.";
+ return false;
+ }
+
+ try
+ {
+ var _ = new MailAddress(value);
+ }
+ catch (FormatException)
+ {
+ message = "The format of E-Mail is bad.";
+ return false;
+ }
+ message = ValidationConstants.SuccessMessage;
+ return true;
+ }
+ }
+
+ public class PhoneNumberValidator : OptionalStringValidator
+ {
+ protected override bool DoValidate(string value, out string message)
+ {
+ if (value.Length > 14)
+ {
+ message = "Phone number is too long.";
+ return false;
+ }
+
+ foreach (var c in value)
+ {
+ if (!char.IsDigit(c))
+ {
+ message = "Phone number can only contain digit.";
+ return false;
+ }
+ }
+
+ message = ValidationConstants.SuccessMessage;
+ return true;
+ }
+ }
}
}
|