diff options
7 files changed, 73 insertions, 10 deletions
diff --git a/BackEnd/Timeline.Tests/IntegratedTests/TimelineTest.cs b/BackEnd/Timeline.Tests/IntegratedTests/TimelineTest.cs index bbfe4ab3..d7832b60 100644 --- a/BackEnd/Timeline.Tests/IntegratedTests/TimelineTest.cs +++ b/BackEnd/Timeline.Tests/IntegratedTests/TimelineTest.cs @@ -438,5 +438,17 @@ namespace Timeline.Tests.IntegratedTests timeline.Postable.Should().Be(false);
}
}
+
+ [Theory]
+ [InlineData("")]
+ [InlineData("default")]
+ public async Task Patch_Timeline_Color_Default(string value)
+ {
+ using var client = await CreateClientAsUser();
+ var timeline = await client.TestPatchAsync<HttpTimeline>("timelines/t1", new HttpTimelinePatchRequest { Color = "#111111" });
+ timeline.Color.Should().NotBeNull();
+ var timeline2 = await client.TestPatchAsync<HttpTimeline>("timelines/t1", new HttpTimelinePatchRequest { Color = value });
+ timeline2.Color.Should().BeNull();
+ }
}
}
diff --git a/BackEnd/Timeline/Models/Http/HttpTimelinePatchRequest.cs b/BackEnd/Timeline/Models/Http/HttpTimelinePatchRequest.cs index 9accb6fc..35667af2 100644 --- a/BackEnd/Timeline/Models/Http/HttpTimelinePatchRequest.cs +++ b/BackEnd/Timeline/Models/Http/HttpTimelinePatchRequest.cs @@ -31,7 +31,7 @@ namespace Timeline.Models.Http /// <summary>
/// New color. Null for not change.
/// </summary>
- [Color]
+ [Color(PermitDefault = true, PermitEmpty = true)]
public string? Color { get; set; }
}
}
diff --git a/BackEnd/Timeline/Models/Http/HttpTimelinePostPatchRequest.cs b/BackEnd/Timeline/Models/Http/HttpTimelinePostPatchRequest.cs index 2c6edf66..cb576a74 100644 --- a/BackEnd/Timeline/Models/Http/HttpTimelinePostPatchRequest.cs +++ b/BackEnd/Timeline/Models/Http/HttpTimelinePostPatchRequest.cs @@ -13,7 +13,7 @@ namespace Timeline.Models.Http /// <summary>
/// Change the color. Null for not change.
/// </summary>
- [Color]
+ [Color(PermitEmpty = true, PermitDefault = true)]
public string? Color { get; set; }
}
}
diff --git a/BackEnd/Timeline/Models/Validation/ColorValidator.cs b/BackEnd/Timeline/Models/Validation/ColorValidator.cs index c5ad833d..4f7accc5 100644 --- a/BackEnd/Timeline/Models/Validation/ColorValidator.cs +++ b/BackEnd/Timeline/Models/Validation/ColorValidator.cs @@ -4,8 +4,22 @@ namespace Timeline.Models.Validation {
public class ColorValidator : Validator<string>
{
+ public bool PermitEmpty { get; set; } = false;
+ public bool PermitDefault { get; set; } = false;
+ public string DefaultValue { get; set; } = "default";
+
protected override (bool, string) DoValidate(string value)
{
+ if (PermitEmpty && value.Length == 0)
+ {
+ return (true, GetSuccessMessage());
+ }
+
+ if (PermitDefault && value == DefaultValue)
+ {
+ return (true, GetSuccessMessage());
+ }
+
if (!value.StartsWith('#'))
{
return (false, "Color must starts with '#'.");
@@ -32,9 +46,29 @@ namespace Timeline.Models.Validation [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)]
public class ColorAttribute : ValidateWithAttribute
{
+ private ColorValidator Validator => (ColorValidator)_validator;
+
public ColorAttribute() : base(typeof(ColorValidator))
{
}
+
+ public bool PermitEmpty
+ {
+ get => Validator.PermitEmpty;
+ set => Validator.PermitEmpty = value;
+ }
+
+ public bool PermitDefault
+ {
+ get => Validator.PermitDefault;
+ set => Validator.PermitDefault = value;
+ }
+
+ public string DefaultValue
+ {
+ get => Validator.DefaultValue;
+ set => Validator.DefaultValue = value;
+ }
}
}
diff --git a/BackEnd/Timeline/Models/Validation/Validator.cs b/BackEnd/Timeline/Models/Validation/Validator.cs index d334960e..0e1f7445 100644 --- a/BackEnd/Timeline/Models/Validation/Validator.cs +++ b/BackEnd/Timeline/Models/Validation/Validator.cs @@ -77,7 +77,7 @@ namespace Timeline.Models.Validation AllowMultiple = false)]
public class ValidateWithAttribute : ValidationAttribute
{
- private readonly IValidator _validator;
+ protected readonly IValidator _validator;
/// <summary>
/// Create with a given validator.
diff --git a/BackEnd/Timeline/Services/Timeline/TimelinePostService.cs b/BackEnd/Timeline/Services/Timeline/TimelinePostService.cs index ee1002e0..ae034767 100644 --- a/BackEnd/Timeline/Services/Timeline/TimelinePostService.cs +++ b/BackEnd/Timeline/Services/Timeline/TimelinePostService.cs @@ -26,6 +26,7 @@ namespace Timeline.Services.Timeline private readonly IImageService _imageValidator;
private readonly IClock _clock;
private readonly ColorValidator _colorValidator = new ColorValidator();
+ private readonly ColorValidator _colorValidatorAllowEmptyAndDefault = new ColorValidator() { PermitEmpty = true, PermitDefault = true };
public TimelinePostService(ILogger<TimelinePostService> logger, DatabaseContext database, IBasicTimelineService basicTimelineService, IBasicUserService basicUserService, IDataManager dataManager, IImageService imageValidator, IClock clock)
{
@@ -38,9 +39,9 @@ namespace Timeline.Services.Timeline _clock = clock;
}
- private void CheckColor(string color, string paramName)
+ private void CheckColor(string color, string paramName, bool allowEmptyOrDefault)
{
- if (!_colorValidator.Validate(color, out var message))
+ if (!(allowEmptyOrDefault ? _colorValidatorAllowEmptyAndDefault : _colorValidator).Validate(color, out var message))
throw new ArgumentException(string.Format(Resource.ExceptionColorInvalid, message), paramName);
}
@@ -166,7 +167,7 @@ namespace Timeline.Services.Timeline throw new ArgumentNullException(nameof(request));
if (request.Color is not null)
- CheckColor(request.Color, nameof(request));
+ CheckColor(request.Color, nameof(request), false);
if (request.DataList is null)
throw new ArgumentException(Resource.ExceptionDataListNull, nameof(request));
@@ -269,7 +270,7 @@ namespace Timeline.Services.Timeline throw new ArgumentNullException(nameof(request));
if (request.Color is not null)
- CheckColor(request.Color, nameof(request));
+ CheckColor(request.Color, nameof(request), true);
request.Time = request.Time?.MyToUtc();
@@ -287,7 +288,16 @@ namespace Timeline.Services.Timeline entity.Time = request.Time.Value;
if (request.Color is not null)
- entity.Color = request.Color;
+ {
+ if (request.Color.Length == 0 || request.Color == "default")
+ {
+ entity.Color = null;
+ }
+ else
+ {
+ entity.Color = request.Color;
+ }
+ }
entity.LastUpdated = _clock.GetCurrentTime();
diff --git a/BackEnd/Timeline/Services/Timeline/TimelineService.cs b/BackEnd/Timeline/Services/Timeline/TimelineService.cs index 920fcc74..6f22ff05 100644 --- a/BackEnd/Timeline/Services/Timeline/TimelineService.cs +++ b/BackEnd/Timeline/Services/Timeline/TimelineService.cs @@ -23,7 +23,7 @@ namespace Timeline.Services.Timeline private readonly IClock _clock;
private readonly TimelineNameValidator _timelineNameValidator = new TimelineNameValidator();
- private readonly ColorValidator _colorValidator = new ColorValidator();
+ private readonly ColorValidator _colorValidator = new ColorValidator() { PermitDefault = true, PermitEmpty = true };
public TimelineService(ILoggerFactory loggerFactory, DatabaseContext database, IBasicUserService userService, IClock clock)
: base(loggerFactory, database, userService, clock)
@@ -119,7 +119,14 @@ namespace Timeline.Services.Timeline if (newProperties.Color is not null)
{
changed = true;
- entity.Color = newProperties.Color;
+ if (newProperties.Color.Length == 0 || newProperties.Color == "default")
+ {
+ entity.Color = null;
+ }
+ else
+ {
+ entity.Color = newProperties.Color;
+ }
}
if (changed)
|