File: ValidationsGenerator\ValidationsGenerator.NoOp.cs
Web Access
Project: src\src\Http\Http.Extensions\test\Microsoft.AspNetCore.Http.Extensions.Tests.csproj (Microsoft.AspNetCore.Http.Extensions.Tests)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
namespace Microsoft.AspNetCore.Http.ValidationsGenerator.Tests;
 
public partial class ValidationsGeneratorTests : ValidationsGeneratorTestBase
{
    [Fact]
    public async Task DoesNotEmitIfNoAddValidationCallExists()
    {
        // Arrange
        var source = """
using System;
using System.ComponentModel.DataAnnotations;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Validation;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection;
 
var builder = WebApplication.CreateBuilder();
 
var app = builder.Build();
 
app.MapPost("/complex-type", (ComplexType complexType) => Results.Ok("Passed"));
 
app.Run();
 
public class ComplexType
{
    [Range(10, 100)]
    public int IntegerWithRange { get; set; } = 10;
}
""";
        await Verify(source, out var compilation);
        // Verify that we don't validate types if no AddValidation call exists
        await VerifyEndpoint(compilation, "/complex-type", async (endpoint, serviceProvider) =>
        {
            var payload = """
                {
                    "IntegerWithRange": 5
                }
                """{
                    "IntegerWithRange": 5
                }
                """;
            var context = CreateHttpContextWithPayload(payload, serviceProvider);
 
            await endpoint.RequestDelegate(context);
 
            Assert.Equal(StatusCodes.Status200OK, context.Response.StatusCode);
        });
    }
 
    [Fact]
    public async Task DoesNotEmitIfNotCorrectAddValidationCallExists()
    {
        // Arrange
        var source = """
using System;
using System.ComponentModel.DataAnnotations;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Validation;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection;
 
var builder = WebApplication.CreateBuilder();
 
builder.Services.AddValidation("example");
SomeExtensions.AddValidation(builder.Services);
 
var app = builder.Build();
 
app.MapPost("/complex-type", (ComplexType complexType) => Results.Ok("Passed"));
 
app.Run();
 
public class ComplexType
{
    [Range(10, 100)]
    public int IntegerWithRange { get; set; } = 10;
}
 
public static class SomeExtensions
{
    public static IServiceCollection AddValidation(this IServiceCollection services, string someString)
    {
        // This is not the correct AddValidation method
        return services;
    }
 
    public static IServiceCollection AddValidation(this IServiceCollection services, Action<ValidationOptions>? configureOptions = null)
    {
        // This is not the correct AddValidation method
        return services;
    }
}
""";
        await Verify(source, out var compilation);
        // Verify that we don't validate types if no AddValidation call exists
        await VerifyEndpoint(compilation, "/complex-type", async (endpoint, serviceProvider) =>
        {
            var payload = """
                {
                    "IntegerWithRange": 5
                }
                """{
                    "IntegerWithRange": 5
                }
                """;
            var context = CreateHttpContextWithPayload(payload, serviceProvider);
 
            await endpoint.RequestDelegate(context);
 
            Assert.Equal(StatusCodes.Status200OK, context.Response.StatusCode);
        });
    }
 
    [Fact]
    public async Task DoesNotEmitForExemptTypes()
    {
        var source = """
using System;
using System.ComponentModel.DataAnnotations;
using System.IO;
using System.IO.Pipelines;
using System.Threading;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Validation;
using Microsoft.Extensions.DependencyInjection;
 
var builder = WebApplication.CreateBuilder();
 
builder.Services.AddValidation();
 
var app = builder.Build();
 
app.MapGet("/exempt-1", (HttpContext context) => Results.Ok("Exempt Passed!"));
app.MapGet("/exempt-2", (HttpRequest request) => Results.Ok("Exempt Passed!"));
app.MapGet("/exempt-3", (HttpResponse response) => Results.Ok("Exempt Passed!"));
app.MapGet("/exempt-4", (IFormCollection formCollection) => Results.Ok("Exempt Passed!"));
app.MapGet("/exempt-5", (IFormFileCollection formFileCollection) => Results.Ok("Exempt Passed!"));
app.MapGet("/exempt-6", (IFormFile formFile) => Results.Ok("Exempt Passed!"));
app.MapGet("/exempt-7", (Stream stream) => Results.Ok("Exempt Passed!"));
app.MapGet("/exempt-8", (PipeReader pipeReader) => Results.Ok("Exempt Passed!"));
app.MapGet("/exempt-9", (CancellationToken cancellationToken) => Results.Ok("Exempt Passed!"));
app.MapPost("/complex-type", (ComplexType complexType) => Results.Ok("Passed"));
 
app.Run();
 
public class ComplexType
{
    [Range(10, 100)]
    public int IntegerWithRange { get; set; } = 10;
}
""";
        await Verify(source, out var compilation);
        // Verify that we can validate non-exempt types
        await VerifyEndpoint(compilation, "/complex-type", async (endpoint, serviceProvider) =>
        {
            var payload = """
                {
                    "IntegerWithRange": 5
                }
                """{
                    "IntegerWithRange": 5
                }
                """;
            var context = CreateHttpContextWithPayload(payload, serviceProvider);
 
            await endpoint.RequestDelegate(context);
 
            var problemDetails = await AssertBadRequest(context);
            Assert.Collection(problemDetails.Errors, kvp =>
            {
                Assert.Equal("IntegerWithRange", kvp.Key);
                Assert.Equal("The field IntegerWithRange must be between 10 and 100.", kvp.Value.Single());
            });
        });
    }
}