aspnetcore/test/Microsoft.AspNetCore.Mvc.Co.../ApiConventionMethodAttribut...

123 lines
4.8 KiB
C#

// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Linq;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.ApiExplorer;
using Microsoft.AspNetCore.Testing;
using Xunit;
namespace Microsoft.AspNetCore.Mvc
{
public class ApiConventionMethodAttributeTest
{
[Fact]
public void Constructor_ThrowsIfConventionMethodIsAnnotatedWithProducesAttribute()
{
// Arrange
var methodName = typeof(ConventionWithProducesAttribute).FullName + '.' + nameof(ConventionWithProducesAttribute.Get);
var attribute = typeof(ProducesAttribute);
var expected = GetErrorMessage(methodName, attribute);
// Act & Assert
ExceptionAssert.ThrowsArgument(
() => new ApiConventionMethodAttribute(typeof(ConventionWithProducesAttribute), nameof(ConventionWithProducesAttribute.Get)),
"conventionType",
expected);
}
public static class ConventionWithProducesAttribute
{
[Produces(typeof(void))]
public static void Get() { }
}
[Fact]
public void Constructor_ThrowsIfTypeIsNotStatic()
{
// Arrange
var methodName = typeof(ConventionWithProducesAttribute).FullName + '.' + nameof(ConventionWithProducesAttribute.Get);
var attribute = typeof(ProducesAttribute);
var expected = $"API convention type '{typeof(object)}' must be a static type.";
// Act & Assert
ExceptionAssert.ThrowsArgument(
() => new ApiConventionMethodAttribute(typeof(object), nameof(object.ToString)),
"conventionType",
expected);
}
[Fact]
public void Constructor_ThrowsIfMethodCannotBeFound()
{
// Arrange
var methodName = typeof(ConventionWithProducesAttribute).FullName + '.' + nameof(ConventionWithProducesAttribute.Get);
var attribute = typeof(ProducesAttribute);
var type = typeof(TestConventions);
var expected = $"A method named 'DoesNotExist' was not found on convention type '{type}'.";
// Act & Assert
ExceptionAssert.ThrowsArgument(
() => new ApiConventionMethodAttribute(typeof(TestConventions), "DoesNotExist"),
"methodName",
expected);
}
[Fact]
public void Constructor_ThrowsIfMethodIsNotPublic()
{
// Arrange
var methodName = typeof(ConventionWithProducesAttribute).FullName + '.' + nameof(ConventionWithProducesAttribute.Get);
var attribute = typeof(ProducesAttribute);
var type = typeof(TestConventions);
var expected = $"A method named 'NotPublic' was not found on convention type '{type}'.";
// Act & Assert
ExceptionAssert.ThrowsArgument(
() => new ApiConventionMethodAttribute(typeof(TestConventions), "NotPublic"),
"methodName",
expected);
}
[Fact]
public void Constructor_ThrowsIfMethodIsAmbiguous()
{
// Arrange
var methodName = typeof(ConventionWithProducesAttribute).FullName + '.' + nameof(ConventionWithProducesAttribute.Get);
var attribute = typeof(ProducesAttribute);
var type = typeof(TestConventions);
var expected = $"Method name 'Method' is ambiguous for convention type '{type}'. More than one method found with the name 'Method'.";
// Act & Assert
ExceptionAssert.ThrowsArgument(
() => new ApiConventionMethodAttribute(typeof(TestConventions), nameof(TestConventions.Method)),
"methodName",
expected);
}
private static class TestConventions
{
internal static void NotPublic() { }
public static void Method(int value) { }
public static void Method(string value) { }
}
private static string GetErrorMessage(string methodName, params Type[] attributes)
{
return $"Method {methodName} is decorated with the following attributes that are not allowed on an API convention method:" +
Environment.NewLine +
string.Join(Environment.NewLine, attributes.Select(a => a.FullName)) +
Environment.NewLine +
$"The following attributes are allowed on API convention methods: {nameof(ProducesResponseTypeAttribute)}, {nameof(ProducesDefaultResponseTypeAttribute)}, {nameof(ApiConventionNameMatchAttribute)}";
}
}
}