File: SupplyParameterFromFormAnalyzerTest.cs
Web Access
Project: src\src\Components\Analyzers\test\Microsoft.AspNetCore.Components.Analyzers.Tests.csproj (Microsoft.AspNetCore.Components.Analyzers.Tests)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;
using TestHelper;
 
namespace Microsoft.AspNetCore.Components.Analyzers.Test;
 
public class SupplyParameterFromFormAnalyzerTest : DiagnosticVerifier
{
    protected override DiagnosticAnalyzer GetCSharpDiagnosticAnalyzer() => new SupplyParameterFromFormAnalyzer();
 
    private static readonly string TestDeclarations = $@"
    namespace {typeof(ParameterAttribute).Namespace}
    {{
        public class {typeof(ParameterAttribute).Name} : System.Attribute
        {{
            public bool CaptureUnmatchedValues {{ get; set; }}
        }}
 
        public class {typeof(CascadingParameterAttribute).Name} : System.Attribute
        {{
        }}
 
        public class SupplyParameterFromFormAttribute : System.Attribute
        {{
            public string Name {{ get; set; }}
            public string FormName {{ get; set; }}
        }}
 
        public interface {typeof(IComponent).Name}
        {{
        }}
 
        public abstract class ComponentBase : {typeof(IComponent).Name}
        {{
        }}
    }}
";
 
    [Fact]
    public void IgnoresPropertiesWithoutSupplyParameterFromFormAttribute()
    {
        var test = $@"
    namespace ConsoleApplication1
    {{
        using {typeof(ParameterAttribute).Namespace};
        class TestComponent : ComponentBase
        {{
            public string MyProperty {{ get; set; }} = ""initial-value"";
        }}
    }}" + TestDeclarations;
 
        VerifyCSharpDiagnostic(test);
    }
 
    [Fact]
    public void IgnoresSupplyParameterFromFormWithoutInitializer()
    {
        var test = $@"
    namespace ConsoleApplication1
    {{
        using {typeof(ParameterAttribute).Namespace};
        class TestComponent : ComponentBase
        {{
            [SupplyParameterFromForm] public string MyProperty {{ get; set; }}
        }}
    }}" + TestDeclarations;
 
        VerifyCSharpDiagnostic(test);
    }
 
    [Fact]
    public void IgnoresNonComponentBaseClasses()
    {
        var test = $@"
    namespace ConsoleApplication1
    {{
        using {typeof(ParameterAttribute).Namespace};
        class NotAComponent
        {{
            [SupplyParameterFromForm] public string MyProperty {{ get; set; }} = ""initial-value"";
        }}
    }}" + TestDeclarations;
 
        VerifyCSharpDiagnostic(test);
    }
 
    [Fact]
    public void ReportsWarningForSupplyParameterFromFormWithInitializer()
    {
        var test = $@"
    namespace ConsoleApplication1
    {{
        using {typeof(ParameterAttribute).Namespace};
        class TestComponent : ComponentBase
        {{
            [SupplyParameterFromForm] public string MyProperty {{ get; set; }} = ""initial-value"";
        }}
    }}" + TestDeclarations;
 
        var expected = new DiagnosticResult
        {
            Id = "BL0008",
            Message = "Property 'ConsoleApplication1.TestComponent.MyProperty' has [SupplyParameterFromForm] and a property initializer. This can be overwritten with null during form posts.",
            Severity = DiagnosticSeverity.Warning,
            Locations = new[]
            {
                new DiagnosticResultLocation("Test0.cs", 7, 53)
            }
        };
 
        VerifyCSharpDiagnostic(test, expected);
    }
 
    [Fact]
    public void ReportsWarningForSupplyParameterFromFormWithObjectInitializer()
    {
        var test = $@"
    namespace ConsoleApplication1
    {{
        using {typeof(ParameterAttribute).Namespace};
        class TestComponent : ComponentBase
        {{
            [SupplyParameterFromForm] public InputModel Input {{ get; set; }} = new InputModel();
        }}
 
        class InputModel
        {{
            public string Value {{ get; set; }} = """";
        }}
    }}" + TestDeclarations;
 
        var expected = new DiagnosticResult
        {
            Id = "BL0008",
            Message = "Property 'ConsoleApplication1.TestComponent.Input' has [SupplyParameterFromForm] and a property initializer. This can be overwritten with null during form posts.",
            Severity = DiagnosticSeverity.Warning,
            Locations = new[]
            {
                new DiagnosticResultLocation("Test0.cs", 7, 57)
            }
        };
 
        VerifyCSharpDiagnostic(test, expected);
    }
 
    [Fact]
    public void IgnoresSupplyParameterFromFormWithNullInitializer()
    {
        var test = $@"
    namespace ConsoleApplication1
    {{
        using {typeof(ParameterAttribute).Namespace};
        class TestComponent : ComponentBase
        {{
            [SupplyParameterFromForm] public string MyProperty {{ get; set; }} = null;
        }}
    }}" + TestDeclarations;
 
        VerifyCSharpDiagnostic(test);
    }
 
    [Fact]
    public void IgnoresSupplyParameterFromFormWithNullForgivingInitializer()
    {
        var test = $@"
    namespace ConsoleApplication1
    {{
        using {typeof(ParameterAttribute).Namespace};
        class TestComponent : ComponentBase
        {{
            [SupplyParameterFromForm] public string MyProperty {{ get; set; }} = null!;
        }}
    }}" + TestDeclarations;
 
        VerifyCSharpDiagnostic(test);
    }
 
    [Fact]
    public void IgnoresSupplyParameterFromFormWithDefaultInitializer()
    {
        var test = $@"
    namespace ConsoleApplication1
    {{
        using {typeof(ParameterAttribute).Namespace};
        class TestComponent : ComponentBase
        {{
            [SupplyParameterFromForm] public string MyProperty {{ get; set; }} = default;
        }}
    }}" + TestDeclarations;
 
        VerifyCSharpDiagnostic(test);
    }
 
    [Fact]
    public void IgnoresSupplyParameterFromFormWithDefaultForgivingInitializer()
    {
        var test = $@"
    namespace ConsoleApplication1
    {{
        using {typeof(ParameterAttribute).Namespace};
        class TestComponent : ComponentBase
        {{
            [SupplyParameterFromForm] public string MyProperty {{ get; set; }} = default!;
        }}
    }}" + TestDeclarations;
 
        VerifyCSharpDiagnostic(test);
    }
 
    [Fact]
    public void WorksWithInheritedComponentBase()
    {
        var test = $@"
    namespace ConsoleApplication1
    {{
        using {typeof(ParameterAttribute).Namespace};
        class BaseComponent : ComponentBase
        {{
        }}
 
        class TestComponent : BaseComponent
        {{
            [SupplyParameterFromForm] public string MyProperty {{ get; set; }} = ""initial-value"";
        }}
    }}" + TestDeclarations;
 
        var expected = new DiagnosticResult
        {
            Id = "BL0008",
            Message = "Property 'ConsoleApplication1.TestComponent.MyProperty' has [SupplyParameterFromForm] and a property initializer. This can be overwritten with null during form posts.",
            Severity = DiagnosticSeverity.Warning,
            Locations = new[]
            {
                new DiagnosticResultLocation("Test0.cs", 11, 53)
            }
        };
 
        VerifyCSharpDiagnostic(test, expected);
    }
}