diff --git a/src/Microsoft.AspNetCore.Mvc.TagHelpers/EnvironmentTagHelper.cs b/src/Microsoft.AspNetCore.Mvc.TagHelpers/EnvironmentTagHelper.cs index c27d116934..3c86f88ab2 100644 --- a/src/Microsoft.AspNetCore.Mvc.TagHelpers/EnvironmentTagHelper.cs +++ b/src/Microsoft.AspNetCore.Mvc.TagHelpers/EnvironmentTagHelper.cs @@ -11,6 +11,8 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers /// /// implementation targeting <environment> elements that conditionally renders /// content based on the current value of . + /// If the environment is not listed in the specified or , + /// or if it is in , the content will not be rendered. /// public class EnvironmentTagHelper : TagHelper { @@ -30,6 +32,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers /// /// A comma separated list of environment names in which the content should be rendered. + /// If the current environment is also in the list, the content will not be rendered. /// /// /// The specified environment names are compared case insensitively to the current value of @@ -37,6 +40,25 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers /// public string Names { get; set; } + /// + /// A comma separated list of environment names in which the content should be rendered. + /// If the current environment is also in the list, the content will not be rendered. + /// + /// + /// The specified environment names are compared case insensitively to the current value of + /// . + /// + public string Include { get; set; } + + /// + /// A comma separated list of environment names in which the content will not be rendered. + /// + /// + /// The specified environment names are compared case insensitively to the current value of + /// . + /// + public string Exclude { get; set; } + protected IHostingEnvironment HostingEnvironment { get; } /// @@ -55,7 +77,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers // Always strip the outer tag name as we never want to render output.TagName = null; - if (string.IsNullOrWhiteSpace(Names)) + if (string.IsNullOrWhiteSpace(Names) && string.IsNullOrWhiteSpace(Include) && string.IsNullOrWhiteSpace(Exclude)) { // No names specified, do nothing return; @@ -68,27 +90,67 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers return; } - var tokenizer = new StringTokenizer(Names, NameSeparator); - var hasEnvironments = false; - foreach (var item in tokenizer) + if (Exclude != null) { - var environment = item.Trim(); - if (environment.HasValue && environment.Length > 0) + var tokenizer = new StringTokenizer(Exclude, NameSeparator); + foreach (var item in tokenizer) { - hasEnvironments = true; - if (environment.Equals(currentEnvironmentName, StringComparison.OrdinalIgnoreCase)) + var environment = item.Trim(); + if (environment.HasValue && environment.Length > 0) { - // Matching environment name found, do nothing - return; + if (environment.Equals(currentEnvironmentName, StringComparison.OrdinalIgnoreCase)) + { + // Matching environment name found, suppress output + output.SuppressOutput(); + return; + } + } + } + } + + var hasEnvironments = false; + if (Names != null) + { + var tokenizer = new StringTokenizer(Names, NameSeparator); + foreach (var item in tokenizer) + { + var environment = item.Trim(); + if (environment.HasValue && environment.Length > 0) + { + hasEnvironments = true; + if (environment.Equals(currentEnvironmentName, StringComparison.OrdinalIgnoreCase)) + { + // Matching environment name found, do nothing + return; + } + } + } + } + + if (Include != null) + { + var tokenizer = new StringTokenizer(Include, NameSeparator); + foreach (var item in tokenizer) + { + var environment = item.Trim(); + if (environment.HasValue && environment.Length > 0) + { + hasEnvironments = true; + if (environment.Equals(currentEnvironmentName, StringComparison.OrdinalIgnoreCase)) + { + // Matching environment name found, do nothing + return; + } } } } if (hasEnvironments) { - // This instance had at least one non-empty environment specified but none of these + // This instance had at least one non-empty environment (names or include) specified but none of these // environments matched the current environment. Suppress the output in this case. output.SuppressOutput(); + return; } } } diff --git a/test/Microsoft.AspNetCore.Mvc.TagHelpers.Test/EnvironmentTagHelperTest.cs b/test/Microsoft.AspNetCore.Mvc.TagHelpers.Test/EnvironmentTagHelperTest.cs index 5e43ace049..57e73c997e 100644 --- a/test/Microsoft.AspNetCore.Mvc.TagHelpers.Test/EnvironmentTagHelperTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.TagHelpers.Test/EnvironmentTagHelperTest.cs @@ -66,6 +66,94 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers.Test ShouldShowContent(namesAttribute, environmentName); } + [Theory] + [InlineData("", "", "")] + [InlineData("", null, "Test")] + [InlineData("Development", "", "")] + [InlineData("", "Development, Test", "")] + [InlineData(null, "development, TEST", "Test")] + [InlineData("Development", "", "Test")] + [InlineData("Development", "Test, Development", "")] + [InlineData("Test", "DEVELOPMENT", null)] + [InlineData("Development", "Test", "")] + [InlineData("Development", null, "Test")] + [InlineData("Development", "Test", "Test")] + [InlineData("Test", "Development", "Test")] + public void ShouldShowContent_IncludeExcludeSpecified(string namesAttribute, string includeAttribute, string excludeAttribute) + { + // Arrange + var content = "content"; + var context = MakeTagHelperContext( + attributes: new TagHelperAttributeList { + { "names", namesAttribute }, + { "include", includeAttribute }, + { "exclude", excludeAttribute }, + }); + var output = MakeTagHelperOutput("environment", childContent: content); + var hostingEnvironment = new Mock(); + hostingEnvironment.SetupProperty(h => h.EnvironmentName, "Development"); + + // Act + var helper = new EnvironmentTagHelper(hostingEnvironment.Object) + { + Names = namesAttribute, + Include = includeAttribute, + Exclude = excludeAttribute, + }; + helper.Process(context, output); + + // Assert + Assert.Null(output.TagName); + Assert.False(output.IsContentModified); + } + + [Theory] + [InlineData(null, "", "Development")] + [InlineData("", "Development", "development")] + [InlineData("", "Test", "Development, test")] + [InlineData("Development", "", "Development")] + [InlineData("Test", "", "Development")] + [InlineData("Development", "Development", "DEVELOPMENT, TEST")] + [InlineData("Development", "Test", "Development")] + [InlineData("Test", "Development", "Development")] + [InlineData("Test", "Test", "Development")] + [InlineData("", "Test", "Test")] + [InlineData("Test", null, "Test")] + [InlineData("Test", "Test", "Test")] + [InlineData("", "Test", null)] + [InlineData("Test", "", "")] + [InlineData("Test", "Test", null)] + public void DoesNotShowContent_IncludeExcludeSpecified(string namesAttribute, string includeAttribute, string excludeAttribute) + { + // Arrange + var content = "content"; + var context = MakeTagHelperContext( + attributes: new TagHelperAttributeList { + { "names", namesAttribute }, + { "include", includeAttribute }, + { "exclude", excludeAttribute }, + }); + var output = MakeTagHelperOutput("environment", childContent: content); + var hostingEnvironment = new Mock(); + hostingEnvironment.SetupProperty(h => h.EnvironmentName, "Development"); + + // Act + var helper = new EnvironmentTagHelper(hostingEnvironment.Object) + { + Names = namesAttribute, + Include = includeAttribute, + Exclude = excludeAttribute, + }; + helper.Process(context, output); + + // Assert + Assert.Null(output.TagName); + Assert.Empty(output.PreContent.GetContent()); + Assert.True(output.Content.GetContent().Length == 0); + Assert.Empty(output.PostContent.GetContent()); + Assert.True(output.IsContentModified); + } + [Theory] [InlineData("NotDevelopment", "Development")] [InlineData("NOTDEVELOPMENT", "Development")] @@ -82,8 +170,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers.Test var context = MakeTagHelperContext(attributes: new TagHelperAttributeList { { "names", namesAttribute } }); var output = MakeTagHelperOutput("environment", childContent: content); var hostingEnvironment = new Mock(); - hostingEnvironment.SetupProperty(h => h.EnvironmentName); - hostingEnvironment.Object.EnvironmentName = environmentName; + hostingEnvironment.SetupProperty(h => h.EnvironmentName, environmentName); // Act var helper = new EnvironmentTagHelper(hostingEnvironment.Object) @@ -108,8 +195,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers.Test attributes: new TagHelperAttributeList { { "names", namesAttribute } }); var output = MakeTagHelperOutput("environment", childContent: content); var hostingEnvironment = new Mock(); - hostingEnvironment.SetupProperty(h => h.EnvironmentName); - hostingEnvironment.Object.EnvironmentName = environmentName; + hostingEnvironment.SetupProperty(h => h.EnvironmentName, environmentName); // Act var helper = new EnvironmentTagHelper(hostingEnvironment.Object)