diff --git a/src/GovUk.Frontend.AspNetCore/TagHelpers/CheckboxesContext.cs b/src/GovUk.Frontend.AspNetCore/TagHelpers/CheckboxesContext.cs index ef62a6ed..2b9f5f14 100644 --- a/src/GovUk.Frontend.AspNetCore/TagHelpers/CheckboxesContext.cs +++ b/src/GovUk.Frontend.AspNetCore/TagHelpers/CheckboxesContext.cs @@ -149,7 +149,7 @@ public override void SetErrorMessage( TemplateString? html, string tagName) { - if (Fieldset is not null) + if (Fieldset is not null && !_fieldsetIsOpen) { throw new InvalidOperationException($"<{tagName}> must be inside <{FieldsetTagName}>."); } diff --git a/src/GovUk.Frontend.AspNetCore/TagHelpers/CheckboxesErrorMessageTagHelper.cs b/src/GovUk.Frontend.AspNetCore/TagHelpers/CheckboxesErrorMessageTagHelper.cs index fc033290..a58751ac 100644 --- a/src/GovUk.Frontend.AspNetCore/TagHelpers/CheckboxesErrorMessageTagHelper.cs +++ b/src/GovUk.Frontend.AspNetCore/TagHelpers/CheckboxesErrorMessageTagHelper.cs @@ -33,7 +33,7 @@ private protected override void SetErrorMessage(TagHelperContent? content, TagHe var attributes = new AttributeCollection(output.Attributes); checkboxesContext.SetErrorMessage( - VisuallyHiddenText, + VisuallyHiddenText is not null ? new TemplateString(VisuallyHiddenText) : null, attributes, content?.ToTemplateString(), output.TagName); diff --git a/src/GovUk.Frontend.AspNetCore/TagHelpers/CheckboxesTagHelper.cs b/src/GovUk.Frontend.AspNetCore/TagHelpers/CheckboxesTagHelper.cs index bb2cc24e..4b63d392 100644 --- a/src/GovUk.Frontend.AspNetCore/TagHelpers/CheckboxesTagHelper.cs +++ b/src/GovUk.Frontend.AspNetCore/TagHelpers/CheckboxesTagHelper.cs @@ -107,7 +107,9 @@ internal CheckboxesTagHelper(IComponentGenerator componentGenerator, IModelHelpe /// public override void Init(TagHelperContext context) { - context.SetContextItem(new CheckboxesContext(Name, For)); + var checkboxesContext = new CheckboxesContext(Name, For); + context.SetContextItem(checkboxesContext); + context.SetContextItem(checkboxesContext); } /// diff --git a/src/GovUk.Frontend.AspNetCore/TagHelpers/DateInputContext.cs b/src/GovUk.Frontend.AspNetCore/TagHelpers/DateInputContext.cs index d51548d0..cbdb0abb 100644 --- a/src/GovUk.Frontend.AspNetCore/TagHelpers/DateInputContext.cs +++ b/src/GovUk.Frontend.AspNetCore/TagHelpers/DateInputContext.cs @@ -128,7 +128,7 @@ public override void SetLabel(bool? isPageHeading, AttributeCollection attribute public override void SetHint(AttributeCollection attributes, TemplateString? html, string tagName) { - if (Fieldset is not null) + if (Fieldset is not null && !_fieldsetIsOpen) { throw new InvalidOperationException($"<{tagName}> must be inside <{FieldsetTagName}>."); } @@ -159,7 +159,7 @@ public void SetErrorMessage( TemplateString? html, string tagName) { - if (Fieldset is not null) + if (Fieldset is not null && !_fieldsetIsOpen) { throw new InvalidOperationException($"<{tagName}> must be inside <{FieldsetTagName}>."); } diff --git a/src/GovUk.Frontend.AspNetCore/TagHelpers/DateInputErrorMessageTagHelper.cs b/src/GovUk.Frontend.AspNetCore/TagHelpers/DateInputErrorMessageTagHelper.cs index 407598f9..13b17eac 100644 --- a/src/GovUk.Frontend.AspNetCore/TagHelpers/DateInputErrorMessageTagHelper.cs +++ b/src/GovUk.Frontend.AspNetCore/TagHelpers/DateInputErrorMessageTagHelper.cs @@ -46,7 +46,7 @@ private protected override void SetErrorMessage(TagHelperContent? content, TagHe dateInputContext.SetErrorMessage( ErrorItems, - VisuallyHiddenText, + VisuallyHiddenText is not null ? new TemplateString(VisuallyHiddenText) : null, attributes, content?.ToTemplateString(), output.TagName); diff --git a/src/GovUk.Frontend.AspNetCore/TagHelpers/FormGroupErrorMessageTagHelperBase.cs b/src/GovUk.Frontend.AspNetCore/TagHelpers/FormGroupErrorMessageTagHelperBase.cs index c2d5e8fd..a9f8a5df 100644 --- a/src/GovUk.Frontend.AspNetCore/TagHelpers/FormGroupErrorMessageTagHelperBase.cs +++ b/src/GovUk.Frontend.AspNetCore/TagHelpers/FormGroupErrorMessageTagHelperBase.cs @@ -52,7 +52,7 @@ private protected virtual void SetErrorMessage(TagHelperContent? content, TagHel var formGroupContext3 = context.GetContextItem(); formGroupContext3.SetErrorMessage( - VisuallyHiddenText, + VisuallyHiddenText is not null ? new TemplateString(VisuallyHiddenText) : null, new AttributeCollection(output.Attributes), content?.ToTemplateString(), output.TagName); diff --git a/src/GovUk.Frontend.AspNetCore/TagHelpers/RadiosContext.cs b/src/GovUk.Frontend.AspNetCore/TagHelpers/RadiosContext.cs index 99d6e38d..0d9371b6 100644 --- a/src/GovUk.Frontend.AspNetCore/TagHelpers/RadiosContext.cs +++ b/src/GovUk.Frontend.AspNetCore/TagHelpers/RadiosContext.cs @@ -149,7 +149,7 @@ public override void SetErrorMessage( TemplateString? html, string tagName) { - if (Fieldset is not null) + if (Fieldset is not null && !_fieldsetIsOpen) { throw new InvalidOperationException($"<{tagName}> must be inside <{FieldsetTagName}>."); } diff --git a/src/GovUk.Frontend.AspNetCore/TagHelpers/RadiosErrorMessageTagHelper.cs b/src/GovUk.Frontend.AspNetCore/TagHelpers/RadiosErrorMessageTagHelper.cs index db25fbb1..b966a9e2 100644 --- a/src/GovUk.Frontend.AspNetCore/TagHelpers/RadiosErrorMessageTagHelper.cs +++ b/src/GovUk.Frontend.AspNetCore/TagHelpers/RadiosErrorMessageTagHelper.cs @@ -31,7 +31,7 @@ private protected override void SetErrorMessage(TagHelperContent? content, TagHe var attributes = new AttributeCollection(output.Attributes); radiosContext.SetErrorMessage( - VisuallyHiddenText, + VisuallyHiddenText is not null ? new TemplateString(VisuallyHiddenText) : null, attributes, content?.ToTemplateString(), output.TagName); diff --git a/tests/GovUk.Frontend.AspNetCore.IntegrationTests/GovUk.Frontend.AspNetCore.IntegrationTests.csproj b/tests/GovUk.Frontend.AspNetCore.IntegrationTests/GovUk.Frontend.AspNetCore.IntegrationTests.csproj index 1b08e71e..1b3b9139 100644 --- a/tests/GovUk.Frontend.AspNetCore.IntegrationTests/GovUk.Frontend.AspNetCore.IntegrationTests.csproj +++ b/tests/GovUk.Frontend.AspNetCore.IntegrationTests/GovUk.Frontend.AspNetCore.IntegrationTests.csproj @@ -12,6 +12,7 @@ + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/CharacterCount.cshtml b/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/CharacterCount.cshtml new file mode 100644 index 00000000..cf0075f4 --- /dev/null +++ b/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/CharacterCount.cshtml @@ -0,0 +1,3 @@ +@model GovUk.Frontend.AspNetCore.IntegrationTests.TagHelperModelBindingTests.CharacterCountTestsModel + + diff --git a/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/CharacterCountOverridden.cshtml b/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/CharacterCountOverridden.cshtml new file mode 100644 index 00000000..fa06a4cf --- /dev/null +++ b/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/CharacterCountOverridden.cshtml @@ -0,0 +1,8 @@ +@model GovUk.Frontend.AspNetCore.IntegrationTests.TagHelperModelBindingTests.CharacterCountTestsModel + + + Overridden label + Overridden hint + Overridden error message + Overridden value + diff --git a/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/Checkboxes.cshtml b/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/Checkboxes.cshtml new file mode 100644 index 00000000..89715053 --- /dev/null +++ b/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/Checkboxes.cshtml @@ -0,0 +1,9 @@ +@model GovUk.Frontend.AspNetCore.IntegrationTests.TagHelperModelBindingTests.CheckboxesTestsModel + + + + + Option 1 + Option 2 + + diff --git a/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/CheckboxesOverridden.cshtml b/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/CheckboxesOverridden.cshtml new file mode 100644 index 00000000..5bcd163c --- /dev/null +++ b/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/CheckboxesOverridden.cshtml @@ -0,0 +1,13 @@ +@model GovUk.Frontend.AspNetCore.IntegrationTests.TagHelperModelBindingTests.CheckboxesTestsModel + + + + + Overridden legend + + Overridden hint + Overridden error message + Option 1 + Option 2 + + diff --git a/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/DateInput.cshtml b/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/DateInput.cshtml new file mode 100644 index 00000000..58044507 --- /dev/null +++ b/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/DateInput.cshtml @@ -0,0 +1,7 @@ +@model GovUk.Frontend.AspNetCore.IntegrationTests.TagHelperModelBindingTests.DateInputTestsModel + + + + + + diff --git a/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/DateInputOverridden.cshtml b/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/DateInputOverridden.cshtml new file mode 100644 index 00000000..6542b494 --- /dev/null +++ b/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/DateInputOverridden.cshtml @@ -0,0 +1,9 @@ +@model GovUk.Frontend.AspNetCore.IntegrationTests.TagHelperModelBindingTests.DateInputTestsModel + + + + Overridden legend + Overridden hint + Overridden error message + + diff --git a/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/DateInputOverriddenItems.cshtml b/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/DateInputOverriddenItems.cshtml new file mode 100644 index 00000000..338f2fde --- /dev/null +++ b/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/DateInputOverriddenItems.cshtml @@ -0,0 +1,7 @@ +@model GovUk.Frontend.AspNetCore.IntegrationTests.TagHelperModelBindingTests.DateInputTestsModel + + + + + + diff --git a/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/FileUpload.cshtml b/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/FileUpload.cshtml new file mode 100644 index 00000000..eb8a5909 --- /dev/null +++ b/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/FileUpload.cshtml @@ -0,0 +1,3 @@ +@model GovUk.Frontend.AspNetCore.IntegrationTests.TagHelperModelBindingTests.FileUploadTestsModel + + diff --git a/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/FileUploadOverridden.cshtml b/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/FileUploadOverridden.cshtml new file mode 100644 index 00000000..427fa3c7 --- /dev/null +++ b/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/FileUploadOverridden.cshtml @@ -0,0 +1,7 @@ +@model GovUk.Frontend.AspNetCore.IntegrationTests.TagHelperModelBindingTests.FileUploadTestsModel + + + Overridden label + Overridden hint + Overridden error message + diff --git a/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/PasswordInput.cshtml b/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/PasswordInput.cshtml new file mode 100644 index 00000000..f0551632 --- /dev/null +++ b/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/PasswordInput.cshtml @@ -0,0 +1,3 @@ +@model GovUk.Frontend.AspNetCore.IntegrationTests.TagHelperModelBindingTests.PasswordInputTestsModel + + diff --git a/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/PasswordInputOverridden.cshtml b/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/PasswordInputOverridden.cshtml new file mode 100644 index 00000000..97deb8b7 --- /dev/null +++ b/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/PasswordInputOverridden.cshtml @@ -0,0 +1,7 @@ +@model GovUk.Frontend.AspNetCore.IntegrationTests.TagHelperModelBindingTests.PasswordInputTestsModel + + + Overridden label + Overridden hint + Overridden error message + diff --git a/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/Radios.cshtml b/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/Radios.cshtml new file mode 100644 index 00000000..40ba8faa --- /dev/null +++ b/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/Radios.cshtml @@ -0,0 +1,9 @@ +@model GovUk.Frontend.AspNetCore.IntegrationTests.TagHelperModelBindingTests.RadiosTestsModel + + + + + Option 1 + Option 2 + + diff --git a/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/RadiosOverridden.cshtml b/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/RadiosOverridden.cshtml new file mode 100644 index 00000000..5a6a77d9 --- /dev/null +++ b/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/RadiosOverridden.cshtml @@ -0,0 +1,13 @@ +@model GovUk.Frontend.AspNetCore.IntegrationTests.TagHelperModelBindingTests.RadiosTestsModel + + + + + Overridden legend + + Overridden hint + Overridden error message + Option 1 + Option 2 + + diff --git a/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/Select.cshtml b/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/Select.cshtml new file mode 100644 index 00000000..76755ca3 --- /dev/null +++ b/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/Select.cshtml @@ -0,0 +1,7 @@ +@model GovUk.Frontend.AspNetCore.IntegrationTests.TagHelperModelBindingTests.SelectTestsModel + + + Choose an option + Option 1 + Option 2 + diff --git a/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/SelectOverridden.cshtml b/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/SelectOverridden.cshtml new file mode 100644 index 00000000..1b8b7dd3 --- /dev/null +++ b/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/SelectOverridden.cshtml @@ -0,0 +1,10 @@ +@model GovUk.Frontend.AspNetCore.IntegrationTests.TagHelperModelBindingTests.SelectTestsModel + + + Overridden label + Overridden hint + Overridden error message + Choose an option + Option 1 + Overridden option + diff --git a/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/TagHelperModelBindingTestsFixture.cs b/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/TagHelperModelBindingTestsFixture.cs new file mode 100644 index 00000000..fe63c81b --- /dev/null +++ b/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/TagHelperModelBindingTestsFixture.cs @@ -0,0 +1,23 @@ +namespace GovUk.Frontend.AspNetCore.IntegrationTests.TagHelperModelBindingTests; + +public class TagHelperModelBindingTestsFixture : ServerFixture +{ + protected override void Configure(IApplicationBuilder app) + { + base.Configure(app); + + app.UseEndpoints(endpoints => endpoints.MapControllers()); + } + + protected override void ConfigureServices(IServiceCollection services) + { + services.AddGovUkFrontend(); + + services + .AddMvc() + .AddRazorOptions(options => + { + options.ViewLocationFormats.Add("/TagHelperModelBindingTests/{0}.cshtml"); + }); + } +} diff --git a/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/Tests.cs b/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/Tests.cs new file mode 100644 index 00000000..0f99b6c0 --- /dev/null +++ b/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/Tests.cs @@ -0,0 +1,652 @@ +using System.ComponentModel.DataAnnotations; +using Microsoft.AspNetCore.Mvc; + +namespace GovUk.Frontend.AspNetCore.IntegrationTests.TagHelperModelBindingTests; + +public class Tests(TagHelperModelBindingTestsFixture fixture) : IClassFixture +{ + [Fact] + public async Task TextInput_RendersCorrectly() + { + var page = await fixture.Browser!.NewPageAsync(); + await page.GotoAsync($"{ServerFixture.BaseUrl}/ModelBindingTests/TextInput"); + + var input = page.Locator("input").First; + Assert.Equal("Text", await input.GetAttributeAsync("name")); + Assert.Equal("Text", await input.GetAttributeAsync("id")); + Assert.Equal("Model value", await input.GetAttributeAsync("value")); + + var label = page.Locator("label").First; + Assert.Equal("Text", await label.GetAttributeAsync("for")); + Assert.Equal("ModelMetadata display name", await label.InnerTextAsync()); + + var hint = page.Locator(".govuk-hint").First; + Assert.Equal("ModelMetadata description", await hint.InnerTextAsync()); + + var errorMessage = page.Locator(".govuk-error-message").First; + Assert.Equal("Error: Model error message", await errorMessage.TextContentAsync()); + } + + [Fact] + public async Task TextInputOverridden_RendersCorrectly() + { + var page = await fixture.Browser!.NewPageAsync(); + await page.GotoAsync($"{ServerFixture.BaseUrl}/ModelBindingTests/TextInputOverridden"); + + var input = page.Locator("input").First; + Assert.Equal("OverriddenName", await input.GetAttributeAsync("name")); + Assert.Equal("OverriddenId", await input.GetAttributeAsync("id")); + Assert.Equal("Overridden value", await input.GetAttributeAsync("value")); + + var label = page.Locator("label").First; + Assert.Equal("OverriddenId", await label.GetAttributeAsync("for")); + Assert.Equal("Overridden label", await label.InnerTextAsync()); + + var hint = page.Locator(".govuk-hint").First; + Assert.Equal("Overridden hint", await hint.InnerTextAsync()); + + var errorMessage = page.Locator(".govuk-error-message").First; + Assert.Equal("Error: Overridden error message", await errorMessage.TextContentAsync()); + } + + [Fact] + public async Task PasswordInput_RendersCorrectly() + { + var page = await fixture.Browser!.NewPageAsync(); + await page.GotoAsync($"{ServerFixture.BaseUrl}/ModelBindingTests/PasswordInput"); + + var input = page.Locator("input[type='password']").First; + Assert.Equal("Password", await input.GetAttributeAsync("name")); + Assert.Equal("Password", await input.GetAttributeAsync("id")); + Assert.Equal("Model value", await input.GetAttributeAsync("value")); + + var label = page.Locator("label").First; + Assert.Equal("Password", await label.GetAttributeAsync("for")); + Assert.Equal("ModelMetadata display name", await label.InnerTextAsync()); + + var hint = page.Locator(".govuk-hint").First; + Assert.Equal("ModelMetadata description", await hint.InnerTextAsync()); + + var errorMessage = page.Locator(".govuk-error-message").First; + Assert.Equal("Error: Model error message", await errorMessage.TextContentAsync()); + } + + [Fact] + public async Task PasswordInputOverridden_RendersCorrectly() + { + var page = await fixture.Browser!.NewPageAsync(); + await page.GotoAsync($"{ServerFixture.BaseUrl}/ModelBindingTests/PasswordInputOverridden"); + + var input = page.Locator("input[type='password']").First; + Assert.Equal("OverriddenName", await input.GetAttributeAsync("name")); + Assert.Equal("OverriddenId", await input.GetAttributeAsync("id")); + Assert.Equal("Overridden value", await input.GetAttributeAsync("value")); + + var label = page.Locator("label").First; + Assert.Equal("OverriddenId", await label.GetAttributeAsync("for")); + Assert.Equal("Overridden label", await label.InnerTextAsync()); + + var hint = page.Locator(".govuk-hint").First; + Assert.Equal("Overridden hint", await hint.InnerTextAsync()); + + var errorMessage = page.Locator(".govuk-error-message").First; + Assert.Equal("Error: Overridden error message", await errorMessage.TextContentAsync()); + } + + [Fact] + public async Task DateInput_RendersCorrectly() + { + var page = await fixture.Browser!.NewPageAsync(); + await page.GotoAsync($"{ServerFixture.BaseUrl}/ModelBindingTests/DateInput"); + + var dayInput = page.Locator("input[name='Date.Day']").First; + Assert.Equal("Date.Day", await dayInput.GetAttributeAsync("name")); + Assert.Equal("Date.Day", await dayInput.GetAttributeAsync("id")); + Assert.Equal("15", await dayInput.GetAttributeAsync("value")); + + var monthInput = page.Locator("input[name='Date.Month']").First; + Assert.Equal("Date.Month", await monthInput.GetAttributeAsync("name")); + Assert.Equal("Date.Month", await monthInput.GetAttributeAsync("id")); + Assert.Equal("3", await monthInput.GetAttributeAsync("value")); + + var yearInput = page.Locator("input[name='Date.Year']").First; + Assert.Equal("Date.Year", await yearInput.GetAttributeAsync("name")); + Assert.Equal("Date.Year", await yearInput.GetAttributeAsync("id")); + Assert.Equal("2024", await yearInput.GetAttributeAsync("value")); + + var legend = page.Locator(".govuk-fieldset__legend").First; + Assert.Equal("ModelMetadata display name", await legend.InnerTextAsync()); + + var hint = page.Locator(".govuk-hint").First; + Assert.Equal("ModelMetadata description", await hint.InnerTextAsync()); + + var errorMessage = page.Locator(".govuk-error-message").First; + Assert.Equal("Error: Model error message", await errorMessage.TextContentAsync()); + } + + [Fact] + public async Task DateInputOverridden_RendersCorrectly() + { + var page = await fixture.Browser!.NewPageAsync(); + await page.GotoAsync($"{ServerFixture.BaseUrl}/ModelBindingTests/DateInputOverridden"); + + var dayInput = page.Locator("input[name='OverriddenName.Day']").First; + Assert.Equal("OverriddenName.Day", await dayInput.GetAttributeAsync("name")); + Assert.Equal("OverriddenId.Day", await dayInput.GetAttributeAsync("id")); + Assert.Equal("15", await dayInput.GetAttributeAsync("value")); + + var monthInput = page.Locator("input[name='OverriddenName.Month']").First; + Assert.Equal("OverriddenName.Month", await monthInput.GetAttributeAsync("name")); + Assert.Equal("OverriddenId.Month", await monthInput.GetAttributeAsync("id")); + Assert.Equal("3", await monthInput.GetAttributeAsync("value")); + + var yearInput = page.Locator("input[name='OverriddenName.Year']").First; + Assert.Equal("OverriddenName.Year", await yearInput.GetAttributeAsync("name")); + Assert.Equal("OverriddenId.Year", await yearInput.GetAttributeAsync("id")); + Assert.Equal("2024", await yearInput.GetAttributeAsync("value")); + + var legend = page.Locator(".govuk-fieldset__legend").First; + Assert.Equal("Overridden legend", await legend.InnerTextAsync()); + + var hint = page.Locator(".govuk-hint").First; + Assert.Equal("Overridden hint", await hint.InnerTextAsync()); + + var errorMessage = page.Locator(".govuk-error-message").First; + Assert.Equal("Error: Overridden error message", await errorMessage.TextContentAsync()); + } + + [Fact] + public async Task DateInputOverriddenItems_RendersCorrectly() + { + var page = await fixture.Browser!.NewPageAsync(); + await page.GotoAsync($"{ServerFixture.BaseUrl}/ModelBindingTests/DateInputOverriddenItems"); + + var dayInput = page.Locator("input[name='OverriddenDayName']").First; + Assert.Equal("OverriddenDayId", await dayInput.GetAttributeAsync("id")); + Assert.Equal("1", await dayInput.GetAttributeAsync("value")); + + var monthInput = page.Locator("input[name='OverriddenMonthName']").First; + Assert.Equal("OverriddenMonthId", await monthInput.GetAttributeAsync("id")); + Assert.Equal("2", await monthInput.GetAttributeAsync("value")); + + var yearInput = page.Locator("input[name='OverriddenYearName']").First; + Assert.Equal("OverriddenYearId", await yearInput.GetAttributeAsync("id")); + Assert.Equal("2020", await yearInput.GetAttributeAsync("value")); + } + + [Fact] + public async Task Textarea_RendersCorrectly() + { + var page = await fixture.Browser!.NewPageAsync(); + await page.GotoAsync($"{ServerFixture.BaseUrl}/ModelBindingTests/Textarea"); + + var textarea = page.Locator("textarea").First; + Assert.Equal("Text", await textarea.GetAttributeAsync("name")); + Assert.Equal("Text", await textarea.GetAttributeAsync("id")); + Assert.Equal("Model value", await textarea.InputValueAsync()); + + var label = page.Locator("label").First; + Assert.Equal("Text", await label.GetAttributeAsync("for")); + Assert.Equal("ModelMetadata display name", await label.InnerTextAsync()); + + var hint = page.Locator(".govuk-hint").First; + Assert.Equal("ModelMetadata description", await hint.InnerTextAsync()); + + var errorMessage = page.Locator(".govuk-error-message").First; + Assert.Equal("Error: Model error message", await errorMessage.TextContentAsync()); + } + + [Fact] + public async Task TextareaOverridden_RendersCorrectly() + { + var page = await fixture.Browser!.NewPageAsync(); + await page.GotoAsync($"{ServerFixture.BaseUrl}/ModelBindingTests/TextareaOverridden"); + + var textarea = page.Locator("textarea").First; + Assert.Equal("OverriddenName", await textarea.GetAttributeAsync("name")); + Assert.Equal("OverriddenId", await textarea.GetAttributeAsync("id")); + Assert.Equal("Overridden value", await textarea.InputValueAsync()); + + var label = page.Locator("label").First; + Assert.Equal("OverriddenId", await label.GetAttributeAsync("for")); + Assert.Equal("Overridden label", await label.InnerTextAsync()); + + var hint = page.Locator(".govuk-hint").First; + Assert.Equal("Overridden hint", await hint.InnerTextAsync()); + + var errorMessage = page.Locator(".govuk-error-message").First; + Assert.Equal("Error: Overridden error message", await errorMessage.TextContentAsync()); + } + + [Fact] + public async Task CharacterCount_RendersCorrectly() + { + var page = await fixture.Browser!.NewPageAsync(); + await page.GotoAsync($"{ServerFixture.BaseUrl}/ModelBindingTests/CharacterCount"); + + var textarea = page.Locator("textarea").First; + Assert.Equal("Text", await textarea.GetAttributeAsync("name")); + Assert.Equal("Text", await textarea.GetAttributeAsync("id")); + Assert.Equal("Model value", await textarea.InputValueAsync()); + + var label = page.Locator("label").First; + Assert.Equal("Text", await label.GetAttributeAsync("for")); + Assert.Equal("ModelMetadata display name", await label.InnerTextAsync()); + + var hint = page.Locator(".govuk-hint").First; + Assert.Equal("ModelMetadata description", await hint.InnerTextAsync()); + + var errorMessage = page.Locator(".govuk-error-message").First; + Assert.Equal("Error: Model error message", await errorMessage.TextContentAsync()); + } + + [Fact] + public async Task CharacterCountOverridden_RendersCorrectly() + { + var page = await fixture.Browser!.NewPageAsync(); + await page.GotoAsync($"{ServerFixture.BaseUrl}/ModelBindingTests/CharacterCountOverridden"); + + var textarea = page.Locator("textarea").First; + Assert.Equal("OverriddenName", await textarea.GetAttributeAsync("name")); + Assert.Equal("OverriddenId", await textarea.GetAttributeAsync("id")); + Assert.Equal("Overridden value", await textarea.InputValueAsync()); + + var label = page.Locator("label").First; + Assert.Equal("OverriddenId", await label.GetAttributeAsync("for")); + Assert.Equal("Overridden label", await label.InnerTextAsync()); + + var hint = page.Locator(".govuk-hint").First; + Assert.Equal("Overridden hint", await hint.InnerTextAsync()); + + var errorMessage = page.Locator(".govuk-error-message").First; + Assert.Equal("Error: Overridden error message", await errorMessage.TextContentAsync()); + } + + [Fact] + public async Task FileUpload_RendersCorrectly() + { + var page = await fixture.Browser!.NewPageAsync(); + await page.GotoAsync($"{ServerFixture.BaseUrl}/ModelBindingTests/FileUpload"); + + var input = page.Locator("input[type='file']").First; + Assert.Equal("File", await input.GetAttributeAsync("name")); + Assert.Equal("File", await input.GetAttributeAsync("id")); + + var label = page.Locator("label").First; + Assert.Equal("File", await label.GetAttributeAsync("for")); + Assert.Equal("ModelMetadata display name", await label.InnerTextAsync()); + + var hint = page.Locator(".govuk-hint").First; + Assert.Equal("ModelMetadata description", await hint.InnerTextAsync()); + + var errorMessage = page.Locator(".govuk-error-message").First; + Assert.Equal("Error: Model error message", await errorMessage.TextContentAsync()); + } + + [Fact] + public async Task FileUploadOverridden_RendersCorrectly() + { + var page = await fixture.Browser!.NewPageAsync(); + await page.GotoAsync($"{ServerFixture.BaseUrl}/ModelBindingTests/FileUploadOverridden"); + + var input = page.Locator("input[type='file']").First; + Assert.Equal("OverriddenName", await input.GetAttributeAsync("name")); + Assert.Equal("OverriddenId", await input.GetAttributeAsync("id")); + + var label = page.Locator("label").First; + Assert.Equal("OverriddenId", await label.GetAttributeAsync("for")); + Assert.Equal("Overridden label", await label.InnerTextAsync()); + + var hint = page.Locator(".govuk-hint").First; + Assert.Equal("Overridden hint", await hint.InnerTextAsync()); + + var errorMessage = page.Locator(".govuk-error-message").First; + Assert.Equal("Error: Overridden error message", await errorMessage.TextContentAsync()); + } + + [Fact] + public async Task Select_RendersCorrectly() + { + var page = await fixture.Browser!.NewPageAsync(); + await page.GotoAsync($"{ServerFixture.BaseUrl}/ModelBindingTests/Select"); + + var select = page.Locator("select").First; + Assert.Equal("Option", await select.GetAttributeAsync("name")); + Assert.Equal("Option", await select.GetAttributeAsync("id")); + Assert.Equal("option2", await select.InputValueAsync()); + + var label = page.Locator("label").First; + Assert.Equal("Option", await label.GetAttributeAsync("for")); + Assert.Equal("ModelMetadata display name", await label.InnerTextAsync()); + + var hint = page.Locator(".govuk-hint").First; + Assert.Equal("ModelMetadata description", await hint.InnerTextAsync()); + + var errorMessage = page.Locator(".govuk-error-message").First; + Assert.Equal("Error: Model error message", await errorMessage.TextContentAsync()); + } + + [Fact] + public async Task SelectOverridden_RendersCorrectly() + { + var page = await fixture.Browser!.NewPageAsync(); + await page.GotoAsync($"{ServerFixture.BaseUrl}/ModelBindingTests/SelectOverridden"); + + var select = page.Locator("select").First; + Assert.Equal("OverriddenName", await select.GetAttributeAsync("name")); + Assert.Equal("OverriddenId", await select.GetAttributeAsync("id")); + Assert.Equal("overridden-value", await select.InputValueAsync()); + + var label = page.Locator("label").First; + Assert.Equal("OverriddenId", await label.GetAttributeAsync("for")); + Assert.Equal("Overridden label", await label.InnerTextAsync()); + + var hint = page.Locator(".govuk-hint").First; + Assert.Equal("Overridden hint", await hint.InnerTextAsync()); + + var errorMessage = page.Locator(".govuk-error-message").First; + Assert.Equal("Error: Overridden error message", await errorMessage.TextContentAsync()); + } + + [Fact] + public async Task Checkboxes_RendersCorrectly() + { + var page = await fixture.Browser!.NewPageAsync(); + await page.GotoAsync($"{ServerFixture.BaseUrl}/ModelBindingTests/Checkboxes"); + + var checkbox1 = page.Locator("input[value='option1']").First; + Assert.Equal("Options", await checkbox1.GetAttributeAsync("name")); + Assert.Equal("Options", await checkbox1.GetAttributeAsync("id")); + Assert.False(await checkbox1.IsCheckedAsync()); + + var checkbox2 = page.Locator("input[value='option2']").First; + Assert.Equal("Options", await checkbox2.GetAttributeAsync("name")); + Assert.Equal("Options-2", await checkbox2.GetAttributeAsync("id")); + Assert.True(await checkbox2.IsCheckedAsync()); + + var hint = page.Locator(".govuk-hint").First; + Assert.Equal("ModelMetadata description", await hint.InnerTextAsync()); + + var errorMessage = page.Locator(".govuk-error-message").First; + Assert.Equal("Error: Model error message", await errorMessage.TextContentAsync()); + } + + [Fact] + public async Task CheckboxesOverridden_RendersCorrectly() + { + var page = await fixture.Browser!.NewPageAsync(); + await page.GotoAsync($"{ServerFixture.BaseUrl}/ModelBindingTests/CheckboxesOverridden"); + + var checkbox1 = page.Locator("input[value='option1']").First; + Assert.Equal("OverriddenName", await checkbox1.GetAttributeAsync("name")); + Assert.Equal("OverriddenIdPrefix", await checkbox1.GetAttributeAsync("id")); + Assert.True(await checkbox1.IsCheckedAsync()); + + var checkbox2 = page.Locator("input[value='option2']").First; + Assert.Equal("OverriddenName", await checkbox2.GetAttributeAsync("name")); + Assert.Equal("OverriddenIdPrefix-2", await checkbox2.GetAttributeAsync("id")); + Assert.False(await checkbox2.IsCheckedAsync()); + + var hint = page.Locator(".govuk-hint").First; + Assert.Equal("Overridden hint", await hint.InnerTextAsync()); + + var errorMessage = page.Locator(".govuk-error-message").First; + Assert.Equal("Error: Overridden error message", await errorMessage.TextContentAsync()); + } + + [Fact] + public async Task Radios_RendersCorrectly() + { + var page = await fixture.Browser!.NewPageAsync(); + await page.GotoAsync($"{ServerFixture.BaseUrl}/ModelBindingTests/Radios"); + + var radio1 = page.Locator("input[value='option1']").First; + Assert.Equal("Option", await radio1.GetAttributeAsync("name")); + Assert.Equal("Option", await radio1.GetAttributeAsync("id")); + Assert.False(await radio1.IsCheckedAsync()); + + var radio2 = page.Locator("input[value='option2']").First; + Assert.Equal("Option", await radio2.GetAttributeAsync("name")); + Assert.Equal("Option-2", await radio2.GetAttributeAsync("id")); + Assert.True(await radio2.IsCheckedAsync()); + + var hint = page.Locator(".govuk-hint").First; + Assert.Equal("ModelMetadata description", await hint.InnerTextAsync()); + + var errorMessage = page.Locator(".govuk-error-message").First; + Assert.Equal("Error: Model error message", await errorMessage.TextContentAsync()); + } + + [Fact] + public async Task RadiosOverridden_RendersCorrectly() + { + var page = await fixture.Browser!.NewPageAsync(); + await page.GotoAsync($"{ServerFixture.BaseUrl}/ModelBindingTests/RadiosOverridden"); + + var radio1 = page.Locator("input[value='option1']").First; + Assert.Equal("OverriddenName", await radio1.GetAttributeAsync("name")); + Assert.Equal("OverriddenIdPrefix", await radio1.GetAttributeAsync("id")); + Assert.True(await radio1.IsCheckedAsync()); + + var radio2 = page.Locator("input[value='option2']").First; + Assert.Equal("OverriddenName", await radio2.GetAttributeAsync("name")); + Assert.Equal("OverriddenIdPrefix-2", await radio2.GetAttributeAsync("id")); + Assert.False(await radio2.IsCheckedAsync()); + + var hint = page.Locator(".govuk-hint").First; + Assert.Equal("Overridden hint", await hint.InnerTextAsync()); + + var errorMessage = page.Locator(".govuk-error-message").First; + Assert.Equal("Error: Overridden error message", await errorMessage.TextContentAsync()); + } +} + +[Route("/[controller]/[action]")] +public class ModelBindingTestsController : Controller +{ + [HttpGet] + public IActionResult TextInput() + { + ModelState.SetModelValue(nameof(TextInputTestsModel.Text), "Model value", "Model value"); + ModelState.AddModelError(nameof(TextInputTestsModel.Text), "Model error message"); + return View(new TextInputTestsModel { Text = "Model value" }); + } + + [HttpGet] + public IActionResult TextInputOverridden() + { + ModelState.SetModelValue(nameof(TextInputTestsModel.Text), "Model value", "Model value"); + ModelState.AddModelError(nameof(TextInputTestsModel.Text), "Model error message"); + return View(new TextInputTestsModel { Text = "Model value" }); + } + + [HttpGet] + public IActionResult PasswordInput() + { + ModelState.SetModelValue(nameof(PasswordInputTestsModel.Password), "Model value", "Model value"); + ModelState.AddModelError(nameof(PasswordInputTestsModel.Password), "Model error message"); + return View(new PasswordInputTestsModel { Password = "Model value" }); + } + + [HttpGet] + public IActionResult PasswordInputOverridden() + { + ModelState.SetModelValue(nameof(PasswordInputTestsModel.Password), "Model value", "Model value"); + ModelState.AddModelError(nameof(PasswordInputTestsModel.Password), "Model error message"); + return View(new PasswordInputTestsModel { Password = "Model value" }); + } + + [HttpGet] + public IActionResult DateInput() + { + ModelState.SetModelValue(nameof(DateInputTestsModel.Date), new DateOnly(2024, 3, 15), "15,3,2024"); + ModelState.AddModelError(nameof(DateInputTestsModel.Date), "Model error message"); + return View(new DateInputTestsModel { Date = new DateOnly(2024, 3, 15) }); + } + + [HttpGet] + public IActionResult DateInputOverridden() + { + ModelState.SetModelValue(nameof(DateInputTestsModel.Date), new DateOnly(2024, 3, 15), "15,3,2024"); + ModelState.AddModelError(nameof(DateInputTestsModel.Date), "Model error message"); + return View(new DateInputTestsModel { Date = new DateOnly(2024, 3, 15) }); + } + + [HttpGet] + public IActionResult DateInputOverriddenItems() + { + ModelState.SetModelValue(nameof(DateInputTestsModel.Date), new DateOnly(2024, 3, 15), "15,3,2024"); + ModelState.AddModelError(nameof(DateInputTestsModel.Date), "Model error message"); + return View(new DateInputTestsModel { Date = new DateOnly(2024, 3, 15) }); + } + + [HttpGet] + public IActionResult Textarea() + { + ModelState.SetModelValue(nameof(TextareaTestsModel.Text), "Model value", "Model value"); + ModelState.AddModelError(nameof(TextareaTestsModel.Text), "Model error message"); + return View(new TextareaTestsModel { Text = "Model value" }); + } + + [HttpGet] + public IActionResult TextareaOverridden() + { + ModelState.SetModelValue(nameof(TextareaTestsModel.Text), "Model value", "Model value"); + ModelState.AddModelError(nameof(TextareaTestsModel.Text), "Model error message"); + return View(new TextareaTestsModel { Text = "Model value" }); + } + + [HttpGet] + public IActionResult CharacterCount() + { + ModelState.SetModelValue(nameof(CharacterCountTestsModel.Text), "Model value", "Model value"); + ModelState.AddModelError(nameof(CharacterCountTestsModel.Text), "Model error message"); + return View(new CharacterCountTestsModel { Text = "Model value" }); + } + + [HttpGet] + public IActionResult CharacterCountOverridden() + { + ModelState.SetModelValue(nameof(CharacterCountTestsModel.Text), "Model value", "Model value"); + ModelState.AddModelError(nameof(CharacterCountTestsModel.Text), "Model error message"); + return View(new CharacterCountTestsModel { Text = "Model value" }); + } + + [HttpGet] + public IActionResult FileUpload() + { + ModelState.SetModelValue(nameof(FileUploadTestsModel.File), "", ""); + ModelState.AddModelError(nameof(FileUploadTestsModel.File), "Model error message"); + return View(new FileUploadTestsModel()); + } + + [HttpGet] + public IActionResult FileUploadOverridden() + { + ModelState.SetModelValue(nameof(FileUploadTestsModel.File), "", ""); + ModelState.AddModelError(nameof(FileUploadTestsModel.File), "Model error message"); + return View(new FileUploadTestsModel()); + } + + [HttpGet] + public IActionResult Select() + { + ModelState.SetModelValue(nameof(SelectTestsModel.Option), "option2", "option2"); + ModelState.AddModelError(nameof(SelectTestsModel.Option), "Model error message"); + return View(new SelectTestsModel { Option = "option2" }); + } + + [HttpGet] + public IActionResult SelectOverridden() + { + ModelState.SetModelValue(nameof(SelectTestsModel.Option), "option2", "option2"); + ModelState.AddModelError(nameof(SelectTestsModel.Option), "Model error message"); + return View(new SelectTestsModel { Option = "option2" }); + } + + [HttpGet] + public IActionResult Checkboxes() + { + ModelState.SetModelValue(nameof(CheckboxesTestsModel.Options), new[] { "option2" }, null); + ModelState.AddModelError(nameof(CheckboxesTestsModel.Options), "Model error message"); + return View(new CheckboxesTestsModel { Options = ["option2"] }); + } + + [HttpGet] + public IActionResult CheckboxesOverridden() + { + ModelState.SetModelValue(nameof(CheckboxesTestsModel.Options), new[] { "option2" }, null); + ModelState.AddModelError(nameof(CheckboxesTestsModel.Options), "Model error message"); + return View(new CheckboxesTestsModel { Options = ["option2"] }); + } + + [HttpGet] + public IActionResult Radios() + { + ModelState.SetModelValue(nameof(RadiosTestsModel.Option), "option2", "option2"); + ModelState.AddModelError(nameof(RadiosTestsModel.Option), "Model error message"); + return View(new RadiosTestsModel { Option = "option2" }); + } + + [HttpGet] + public IActionResult RadiosOverridden() + { + ModelState.SetModelValue(nameof(RadiosTestsModel.Option), "option2", "option2"); + ModelState.AddModelError(nameof(RadiosTestsModel.Option), "Model error message"); + return View(new RadiosTestsModel { Option = "option2" }); + } +} + +public record TextInputTestsModel +{ + [Display(Name = "ModelMetadata display name", Description = "ModelMetadata description")] + public string? Text { get; set; } +} + +public record PasswordInputTestsModel +{ + [Display(Name = "ModelMetadata display name", Description = "ModelMetadata description")] + public string? Password { get; set; } +} + +public record DateInputTestsModel +{ + [Display(Name = "ModelMetadata display name", Description = "ModelMetadata description")] + public DateOnly? Date { get; set; } +} + +public record TextareaTestsModel +{ + [Display(Name = "ModelMetadata display name", Description = "ModelMetadata description")] + public string? Text { get; set; } +} + +public record CharacterCountTestsModel +{ + [Display(Name = "ModelMetadata display name", Description = "ModelMetadata description")] + public string? Text { get; set; } +} + +public record FileUploadTestsModel +{ + [Display(Name = "ModelMetadata display name", Description = "ModelMetadata description")] + public IFormFile? File { get; set; } +} + +public record SelectTestsModel +{ + [Display(Name = "ModelMetadata display name", Description = "ModelMetadata description")] + public string? Option { get; set; } +} + +public record CheckboxesTestsModel +{ + [Display(Name = "ModelMetadata display name", Description = "ModelMetadata description")] + public List? Options { get; set; } +} + +public record RadiosTestsModel +{ + [Display(Name = "ModelMetadata display name", Description = "ModelMetadata description")] + public string? Option { get; set; } +} diff --git a/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/TextInput.cshtml b/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/TextInput.cshtml new file mode 100644 index 00000000..ab3f5913 --- /dev/null +++ b/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/TextInput.cshtml @@ -0,0 +1,3 @@ +@model GovUk.Frontend.AspNetCore.IntegrationTests.TagHelperModelBindingTests.TextInputTestsModel + + diff --git a/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/TextInputOverridden.cshtml b/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/TextInputOverridden.cshtml new file mode 100644 index 00000000..badff6ae --- /dev/null +++ b/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/TextInputOverridden.cshtml @@ -0,0 +1,7 @@ +@model GovUk.Frontend.AspNetCore.IntegrationTests.TagHelperModelBindingTests.TextInputTestsModel + + + Overridden label + Overridden hint + Overridden error message + diff --git a/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/Textarea.cshtml b/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/Textarea.cshtml new file mode 100644 index 00000000..be31000e --- /dev/null +++ b/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/Textarea.cshtml @@ -0,0 +1,3 @@ +@model GovUk.Frontend.AspNetCore.IntegrationTests.TagHelperModelBindingTests.TextareaTestsModel + + diff --git a/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/TextareaOverridden.cshtml b/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/TextareaOverridden.cshtml new file mode 100644 index 00000000..b7c3498d --- /dev/null +++ b/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/TextareaOverridden.cshtml @@ -0,0 +1,8 @@ +@model GovUk.Frontend.AspNetCore.IntegrationTests.TagHelperModelBindingTests.TextareaTestsModel + + + Overridden label + Overridden hint + Overridden error message + Overridden value + diff --git a/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/_ViewImports.cshtml b/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/_ViewImports.cshtml new file mode 100644 index 00000000..8ced5bf7 --- /dev/null +++ b/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/_ViewImports.cshtml @@ -0,0 +1,3 @@ +@addTagHelper *, GovUk.Frontend.AspNetCore +@addTagHelper *, GovUk.Frontend.AspNetCore.IntegrationTests +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers diff --git a/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/_ViewStart.cshtml b/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/_ViewStart.cshtml new file mode 100644 index 00000000..36592afb --- /dev/null +++ b/tests/GovUk.Frontend.AspNetCore.IntegrationTests/TagHelperModelBindingTests/_ViewStart.cshtml @@ -0,0 +1,3 @@ +@{ + Layout = "_GovUkPageTemplate"; +}