Skip to content

Commit

Permalink
Minor: Added Test Cases
Browse files Browse the repository at this point in the history
  • Loading branch information
nikunj-bhargava committed Apr 26, 2024
1 parent 134306f commit 555654a
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 17 deletions.
2 changes: 1 addition & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"sdk": {
"version": "8.0.204",
"version": "7.0.2",
"allowPrerelease": false,
"rollForward": "latestMajor"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
using System.Linq;
using System.Reflection;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ApiExplorer;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.ModelBinding;
Expand Down Expand Up @@ -112,17 +111,5 @@ internal static bool IsFromForm(this ApiParameterDescription apiParameter)
return (source == BindingSource.Form || source == BindingSource.FormFile)
|| (elementType != null && typeof(IFormFile).IsAssignableFrom(elementType));
}

internal static bool IsFromFormAttributeUsedWithFormFile(this ApiParameterDescription apiParameter)
{
// Retrieve parameter information
var parameterInfo = ParameterInfo(apiParameter);

// Retrieve attributes from the parameter
var fromFormAttribute = parameterInfo?.GetCustomAttribute<FromFormAttribute>();

return fromFormAttribute != null && parameterInfo?.ParameterType == typeof(IFormFile);

}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.Annotations;
using Swashbuckle.AspNetCore.Swagger;
using Microsoft.AspNetCore.Http;

#if NET7_0_OR_GREATER
using Microsoft.AspNetCore.Http.Metadata;
#endif
Expand Down Expand Up @@ -316,10 +318,10 @@ private IList<OpenApiTag> GenerateOperationTags(ApiDescription apiDescription)

private IList<OpenApiParameter> GenerateParameters(ApiDescription apiDescription, SchemaRepository schemaRespository)
{
if (apiDescription.ParameterDescriptions.Any(apiParam => apiParam.IsFromFormAttributeUsedWithFormFile()))
if (apiDescription.ParameterDescriptions.Any(apiParam => IsFromFormAttributeUsedWithIFormFile(apiParam)))
throw new SwaggerGeneratorException(string.Format(
"Error reading parameter(s) for action {0} as [FromForm] attribute used with IFormFile. " +
"Please refer https://github.com/domaindrivendev/Swashbuckle.AspNetCore/blob/master/README.md#handle-forms-and-file-uploads",
"Please refer to https://github.com/domaindrivendev/Swashbuckle.AspNetCore#handle-forms-and-file-uploads for more information",
apiDescription.ActionDescriptor.DisplayName));

var applicableApiParameters = apiDescription.ParameterDescriptions
Expand Down Expand Up @@ -621,6 +623,17 @@ private OpenApiMediaType CreateResponseMediaType(ModelMetadata modelMetadata, Sc
};
}

private bool IsFromFormAttributeUsedWithIFormFile(ApiParameterDescription apiParameter)
{
// Retrieve parameter information
var parameterInfo = apiParameter.ParameterInfo();

// Check if Parameter has FromForm Attribute
var fromFormAttribute = parameterInfo?.GetCustomAttribute<FromFormAttribute>();

return fromFormAttribute != null && parameterInfo?.ParameterType == typeof(IFormFile);
}

private static readonly Dictionary<string, OperationType> OperationTypeMap = new Dictionary<string, OperationType>
{
{ "GET", OperationType.Get },
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Swashbuckle.AspNetCore.Annotations;
Expand Down Expand Up @@ -84,5 +85,11 @@ public int ActionWithProducesAttribute()
[SwaggerIgnore]
public void ActionWithSwaggerIgnoreAttribute()
{ }

public void ActionHavingIFormFileParamWithFromFormAtribute([FromForm] IFormFile fileUpload)
{ }

public void ActionHavingFromFormAtributeButNotWithIFormFile([FromForm] string param1, IFormFile param2)
{ }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
using Swashbuckle.AspNetCore.TestSupport;
using Xunit;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Server.HttpSys;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Mvc.Controllers;

namespace Swashbuckle.AspNetCore.SwaggerGen.Test
{
Expand Down Expand Up @@ -1409,6 +1409,87 @@ public void GetSwagger_SupportsOption_DocumentFilters()
Assert.Contains("ComplexType", document.Components.Schemas.Keys);
}

[Fact]
public void GetSwagger_Throws_Exception_When_FromForm_Attribute_Used_With_IFormFile()
{
var parameterInfo = typeof(FakeController)
.GetMethod(nameof(FakeController.ActionHavingIFormFileParamWithFromFormAtribute))
.GetParameters()[0];


var subject = Subject(
apiDescriptions: new[]
{
ApiDescriptionFactory.Create<FakeController>(
c => nameof(c.ActionHavingIFormFileParamWithFromFormAtribute),
groupName: "v1",
httpMethod: "POST",
relativePath: "resource",
parameterDescriptions: new[]
{
new ApiParameterDescription
{
Name = "fileUpload", // Name of the parameter
Type = typeof(IFormFile), // Type of the parameter
ParameterDescriptor = new ControllerParameterDescriptor { ParameterInfo = parameterInfo }
}
})
}
);

var exception = Assert.Throws<SwaggerGeneratorException>(() => subject.GetSwagger("v1"));
}

[Fact]
public void GetSwagger_Works_As_Expected_When_FromForm_Attribute_Not_Used_With_IFormFile()
{
var paraminfo = typeof(FakeController)
.GetMethod(nameof(FakeController.ActionHavingFromFormAtributeButNotWithIFormFile))
.GetParameters()[0];

var fileUploadParameterInfo = typeof(FakeController)
.GetMethod(nameof(FakeController.ActionHavingFromFormAtributeButNotWithIFormFile))
.GetParameters()[1];

var subject = Subject(
apiDescriptions: new[]
{
ApiDescriptionFactory.Create<FakeController>(
c => nameof(c.ActionHavingFromFormAtributeButNotWithIFormFile),
groupName: "v1",
httpMethod: "POST",
relativePath: "resource",
parameterDescriptions: new[]
{
new ApiParameterDescription
{
Name = "param1", // Name of the parameter
Type = typeof(string), // Type of the parameter
ParameterDescriptor = new ControllerParameterDescriptor { ParameterInfo = paraminfo }
},
new ApiParameterDescription
{
Name = "param2", // Name of the parameter
Type = typeof(IFormFile), // Type of the parameter
ParameterDescriptor = new ControllerParameterDescriptor { ParameterInfo = fileUploadParameterInfo }
}
})
}
);

var document = subject.GetSwagger("v1");

Assert.Equal("V1", document.Info.Version);
Assert.Equal("Test API", document.Info.Title);
Assert.Equal(new[] { "/resource" }, document.Paths.Keys.ToArray());

var operation = document.Paths["/resource"].Operations[OperationType.Post];
Assert.NotNull(operation.Parameters);
Assert.Equal(2, operation.Parameters.Count);
Assert.Equal("param1", operation.Parameters[0].Name);
Assert.Equal("param2", operation.Parameters[1].Name);
}

private static SwaggerGenerator Subject(
IEnumerable<ApiDescription> apiDescriptions,
SwaggerGeneratorOptions options = null,
Expand Down

0 comments on commit 555654a

Please sign in to comment.