|
|
@@ -1819,11 +1819,84 @@ public class InputTagHelperTest
|
|
|
Assert.Equal(expectedTagName, output.TagName);
|
|
|
}
|
|
|
|
|
|
+ [Fact]
|
|
|
+ public async Task ProcessAsync_CallsGenerateTextBox_InputTypeDateOnly_RendersAsDate()
|
|
|
+ {
|
|
|
+ // Arrange
|
|
|
+ var expectedAttributes = new TagHelperAttributeList
|
|
|
+ {
|
|
|
+ { "type", "date" }, // Calculated; not passed to HtmlGenerator.
|
|
|
+ };
|
|
|
+ var expectedTagName = "not-input";
|
|
|
+
|
|
|
+ var context = new TagHelperContext(
|
|
|
+ tagName: "input",
|
|
|
+ allAttributes: new TagHelperAttributeList()
|
|
|
+ {
|
|
|
+ {"type", "date" }
|
|
|
+ },
|
|
|
+ items: new Dictionary<object, object>(),
|
|
|
+ uniqueId: "test");
|
|
|
+
|
|
|
+ var output = new TagHelperOutput(
|
|
|
+ expectedTagName,
|
|
|
+ attributes: new TagHelperAttributeList(),
|
|
|
+ getChildContentAsync: (useCachedResult, encoder) => Task.FromResult<TagHelperContent>(
|
|
|
+ new DefaultTagHelperContent()))
|
|
|
+ {
|
|
|
+ TagMode = TagMode.SelfClosing,
|
|
|
+ };
|
|
|
+
|
|
|
+ var htmlAttributes = new Dictionary<string, object>
|
|
|
+ {
|
|
|
+ { "type", "date" }
|
|
|
+ };
|
|
|
+
|
|
|
+ var metadataProvider = TestModelMetadataProvider.CreateDefaultProvider();
|
|
|
+
|
|
|
+ var htmlGenerator = new Mock<IHtmlGenerator>(MockBehavior.Strict);
|
|
|
+ var tagHelper = GetTagHelper(
|
|
|
+ htmlGenerator.Object,
|
|
|
+ model: null,
|
|
|
+ propertyName: "DateOnly",
|
|
|
+ metadataProvider: metadataProvider);
|
|
|
+ tagHelper.ViewContext.Html5DateRenderingMode = Html5DateRenderingMode.Rfc3339;
|
|
|
+ tagHelper.InputTypeName = "date";
|
|
|
+ var tagBuilder = new TagBuilder("input");
|
|
|
+ htmlGenerator
|
|
|
+ .Setup(mock => mock.GenerateTextBox(
|
|
|
+ tagHelper.ViewContext,
|
|
|
+ tagHelper.For.ModelExplorer,
|
|
|
+ tagHelper.For.Name,
|
|
|
+ null, // value
|
|
|
+ @"{0:yyyy-MM-dd}",
|
|
|
+ htmlAttributes)) // htmlAttributes
|
|
|
+ .Returns(tagBuilder)
|
|
|
+ .Verifiable();
|
|
|
+
|
|
|
+ // Act
|
|
|
+ await tagHelper.ProcessAsync(context, output);
|
|
|
+
|
|
|
+ // Assert
|
|
|
+ htmlGenerator.Verify();
|
|
|
+
|
|
|
+ Assert.Equal(TagMode.SelfClosing, output.TagMode);
|
|
|
+ Assert.Equal(expectedAttributes, output.Attributes);
|
|
|
+ Assert.Empty(output.PreContent.GetContent());
|
|
|
+ Assert.Equal(string.Empty, output.Content.GetContent());
|
|
|
+ Assert.Empty(output.PostContent.GetContent());
|
|
|
+ Assert.Equal(expectedTagName, output.TagName);
|
|
|
+ }
|
|
|
+
|
|
|
[Theory]
|
|
|
[InlineData("Date", Html5DateRenderingMode.CurrentCulture, "{0:d}", "date")] // Format from [DataType].
|
|
|
[InlineData("Date", Html5DateRenderingMode.Rfc3339, "{0:yyyy-MM-dd}", "date")]
|
|
|
[InlineData("DateTime", Html5DateRenderingMode.CurrentCulture, null, "datetime-local")]
|
|
|
[InlineData("DateTime", Html5DateRenderingMode.Rfc3339, @"{0:yyyy-MM-ddTHH\:mm\:ss.fff}", "datetime-local")]
|
|
|
+ [InlineData("DateOnlyDate", Html5DateRenderingMode.CurrentCulture, "{0:d}", "date")] // Format from [DataType].
|
|
|
+ [InlineData("DateOnlyDate", Html5DateRenderingMode.Rfc3339, "{0:yyyy-MM-dd}", "date")]
|
|
|
+ [InlineData("DateOnly", Html5DateRenderingMode.CurrentCulture, null, "text")] // Format from [DataType].
|
|
|
+ [InlineData("DateOnly", Html5DateRenderingMode.Rfc3339, null, "text")]
|
|
|
[InlineData("DateTimeOffset", Html5DateRenderingMode.CurrentCulture, null, "text")]
|
|
|
[InlineData("DateTimeOffset", Html5DateRenderingMode.Rfc3339, @"{0:yyyy-MM-ddTHH\:mm\:ss.fffK}", "text")]
|
|
|
[InlineData("DateTimeLocal", Html5DateRenderingMode.CurrentCulture, null, "datetime-local")]
|
|
|
@@ -1836,6 +1909,8 @@ public class InputTagHelperTest
|
|
|
[InlineData("Week", Html5DateRenderingMode.Rfc3339, null, "week")]
|
|
|
[InlineData("NullableDate", Html5DateRenderingMode.Rfc3339, "{0:yyyy-MM-dd}", "date")]
|
|
|
[InlineData("NullableDateTime", Html5DateRenderingMode.Rfc3339, @"{0:yyyy-MM-ddTHH\:mm\:ss.fff}", "datetime-local")]
|
|
|
+ [InlineData("NullableDateOnlyDate", Html5DateRenderingMode.Rfc3339, "{0:yyyy-MM-dd}", "date")]
|
|
|
+ [InlineData("NullableDateOnly", Html5DateRenderingMode.Rfc3339, null, "text")]
|
|
|
[InlineData("NullableDateTimeOffset", Html5DateRenderingMode.Rfc3339, @"{0:yyyy-MM-ddTHH\:mm\:ss.fffK}", "text")]
|
|
|
public async Task ProcessAsync_CallsGenerateTextBox_AddsExpectedAttributesForRfc3339(
|
|
|
string propertyName,
|
|
|
@@ -1973,6 +2048,63 @@ public class InputTagHelperTest
|
|
|
Assert.Equal(expectedType, output.TagName);
|
|
|
}
|
|
|
|
|
|
+ // Html5DateRenderingMode.Rfc3339 is enabled by default.
|
|
|
+ [Theory]
|
|
|
+ [InlineData("DateOnlyDate", "2000-01-02", "date")]
|
|
|
+ [InlineData("DateOnly", "02/01/2000", "text")]
|
|
|
+ [ReplaceCulture]
|
|
|
+ public async Task ProcessAsync_CallsGenerateTextBox_ProducesExpectedValue_ForDateOnly(
|
|
|
+ string propertyName,
|
|
|
+ string expectedValue,
|
|
|
+ string expectedType)
|
|
|
+ {
|
|
|
+ // Arrange
|
|
|
+ var expectedAttributes = new TagHelperAttributeList
|
|
|
+ {
|
|
|
+ { "type", expectedType },
|
|
|
+ { "id", propertyName },
|
|
|
+ { "name", propertyName },
|
|
|
+ { "value", expectedValue },
|
|
|
+ };
|
|
|
+
|
|
|
+ var context = new TagHelperContext(
|
|
|
+ tagName: "input",
|
|
|
+ allAttributes: new TagHelperAttributeList(
|
|
|
+ Enumerable.Empty<TagHelperAttribute>()),
|
|
|
+ items: new Dictionary<object, object>(),
|
|
|
+ uniqueId: "test");
|
|
|
+
|
|
|
+ var output = new TagHelperOutput(
|
|
|
+ expectedType,
|
|
|
+ attributes: new TagHelperAttributeList(),
|
|
|
+ getChildContentAsync: (useCachedResult, encoder) => Task.FromResult<TagHelperContent>(
|
|
|
+ new DefaultTagHelperContent()))
|
|
|
+ {
|
|
|
+ TagMode = TagMode.SelfClosing,
|
|
|
+ };
|
|
|
+
|
|
|
+ var metadataProvider = TestModelMetadataProvider.CreateDefaultProvider();
|
|
|
+ var model = new DateOnly(
|
|
|
+ year: 2000,
|
|
|
+ month: 1,
|
|
|
+ day: 2);
|
|
|
+
|
|
|
+ var htmlGenerator = HtmlGeneratorUtilities.GetHtmlGenerator(metadataProvider);
|
|
|
+ var tagHelper = GetTagHelper(
|
|
|
+ htmlGenerator,
|
|
|
+ model: model,
|
|
|
+ propertyName: propertyName,
|
|
|
+ metadataProvider: metadataProvider);
|
|
|
+ tagHelper.ViewContext.Html5DateRenderingMode = Html5DateRenderingMode.Rfc3339;
|
|
|
+
|
|
|
+ // Act
|
|
|
+ await tagHelper.ProcessAsync(context, output);
|
|
|
+
|
|
|
+ // Assert
|
|
|
+ Assert.Equal(expectedAttributes, output.Attributes);
|
|
|
+ Assert.Equal(expectedType, output.TagName);
|
|
|
+ }
|
|
|
+
|
|
|
// Html5DateRenderingMode.Rfc3339 can be disabled.
|
|
|
[Theory]
|
|
|
[InlineData("Date", null, "02/01/2000", "date")]
|
|
|
@@ -2048,6 +2180,67 @@ public class InputTagHelperTest
|
|
|
Assert.Equal(expectedType, output.TagName);
|
|
|
}
|
|
|
|
|
|
+ // Html5DateRenderingMode.Rfc3339 can be disabled.
|
|
|
+ [Theory]
|
|
|
+ [InlineData("DateOnlyDate", null, "02/01/2000", "date")]
|
|
|
+ [InlineData("DateOnlyDate", "{0:d}", "02/01/2000", "date")]
|
|
|
+ [InlineData("DateOnly", null, "02/01/2000", "text")]
|
|
|
+ [ReplaceCulture]
|
|
|
+ public async Task ProcessAsync_CallsGenerateTextBox_ProducesExpectedValue_ForDateOnlyNotRfc3339(
|
|
|
+ string propertyName,
|
|
|
+ string editFormatString,
|
|
|
+ string expectedValue,
|
|
|
+ string expectedType)
|
|
|
+ {
|
|
|
+ // Arrange
|
|
|
+ var expectedAttributes = new TagHelperAttributeList
|
|
|
+ {
|
|
|
+ { "type", expectedType },
|
|
|
+ { "id", propertyName },
|
|
|
+ { "name", propertyName },
|
|
|
+ { "value", expectedValue },
|
|
|
+ };
|
|
|
+
|
|
|
+ var context = new TagHelperContext(
|
|
|
+ tagName: "input",
|
|
|
+ allAttributes: new TagHelperAttributeList(
|
|
|
+ Enumerable.Empty<TagHelperAttribute>()),
|
|
|
+ items: new Dictionary<object, object>(),
|
|
|
+ uniqueId: "test");
|
|
|
+
|
|
|
+ var output = new TagHelperOutput(
|
|
|
+ expectedType,
|
|
|
+ attributes: new TagHelperAttributeList(),
|
|
|
+ getChildContentAsync: (useCachedResult, encoder) => Task.FromResult<TagHelperContent>(
|
|
|
+ new DefaultTagHelperContent()))
|
|
|
+ {
|
|
|
+ TagMode = TagMode.SelfClosing,
|
|
|
+ };
|
|
|
+
|
|
|
+ var metadataProvider = TestModelMetadataProvider.CreateDefaultProvider();
|
|
|
+
|
|
|
+ var model = new DateOnly(
|
|
|
+ year: 2000,
|
|
|
+ month: 1,
|
|
|
+ day: 2);
|
|
|
+
|
|
|
+ var htmlGenerator = HtmlGeneratorUtilities.GetHtmlGenerator(metadataProvider);
|
|
|
+ var tagHelper = GetTagHelper(
|
|
|
+ htmlGenerator,
|
|
|
+ model: model,
|
|
|
+ propertyName: propertyName,
|
|
|
+ metadataProvider: metadataProvider);
|
|
|
+ tagHelper.ViewContext.Html5DateRenderingMode = Html5DateRenderingMode.CurrentCulture;
|
|
|
+ tagHelper.Format = editFormatString;
|
|
|
+
|
|
|
+ // Act
|
|
|
+ await tagHelper.ProcessAsync(context, output);
|
|
|
+
|
|
|
+ // Assert
|
|
|
+ Assert.Equal(expectedAttributes, output.Attributes);
|
|
|
+ Assert.Equal(expectedType, output.TagName);
|
|
|
+ }
|
|
|
+
|
|
|
// Html5DateRenderingMode.Rfc3339 can be disabled.
|
|
|
[Theory]
|
|
|
[InlineData("Month", "month")]
|
|
|
@@ -2184,6 +2377,11 @@ public class InputTagHelperTest
|
|
|
|
|
|
public DateTime DateTime { get; set; }
|
|
|
|
|
|
+ [DataType(DataType.Date)]
|
|
|
+ public DateOnly DateOnlyDate { get; set; }
|
|
|
+
|
|
|
+ public DateOnly DateOnly { get; set; }
|
|
|
+
|
|
|
public DateTimeOffset DateTimeOffset { get; set; }
|
|
|
|
|
|
[DataType(DataType.Date)]
|
|
|
@@ -2191,6 +2389,11 @@ public class InputTagHelperTest
|
|
|
|
|
|
public DateTime? NullableDateTime { get; set; }
|
|
|
|
|
|
+ [DataType(DataType.Date)]
|
|
|
+ public DateOnly? NullableDateOnlyDate { get; set; }
|
|
|
+
|
|
|
+ public DateOnly? NullableDateOnly { get; set; }
|
|
|
+
|
|
|
public DateTimeOffset? NullableDateTimeOffset { get; set; }
|
|
|
|
|
|
[DataType("datetime-local")]
|