diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 5043a7c..eb3eb49 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -5,6 +5,7 @@ on: branches: - master - dev + - v3 - feature/* jobs: @@ -13,7 +14,7 @@ jobs: strategy: matrix: os: [ 'windows-latest' ] - dotnet: [ '3.1.301' ] + dotnet: [ '3.1.302' ] runs-on: ${{ matrix.os }} diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index f1f7803..a89167c 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -11,7 +11,7 @@ jobs: strategy: matrix: os: [ 'windows-latest' ] - dotnet: [ '3.1.301' ] + dotnet: [ '3.1.302' ] runs-on: ${{ matrix.os }} diff --git a/.github/workflows/release-all.yaml b/.github/workflows/release-all.yaml index 8271331..a74e349 100644 --- a/.github/workflows/release-all.yaml +++ b/.github/workflows/release-all.yaml @@ -7,6 +7,7 @@ on: - release/configjson-* - release/di-* - release/swagger-* + - release/swaggercore-* jobs: build_test_package_release: @@ -14,7 +15,7 @@ jobs: strategy: matrix: os: [ 'windows-latest' ] - dotnet: [ '3.1.301' ] + dotnet: [ '3.1.302' ] runs-on: ${{ matrix.os }} @@ -89,12 +90,21 @@ jobs: dotnet build ./src/Aliencube.AzureFunctions.Extensions.DependencyInjection -c Release -p:Version=${{ steps.release.outputs.version }} -v minimal dotnet build ./test/Aliencube.AzureFunctions.Extensions.DependencyInjection.Tests -c Release + - name: Build solution for OpenApi Core + if: steps.release.outputs.module == 'swaggercore' + shell: pwsh + run: | + dir + dotnet build ./src/Aliencube.AzureFunctions.Extensions.OpenApi.Core -c Release -p:Version=${{ steps.release.outputs.version }} -v minimal + dotnet build ./test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests -c Release + - name: Build solution for OpenApi if: steps.release.outputs.module == 'swagger' shell: pwsh run: | dir - dotnet build . -c Release -p:Version=${{ steps.release.outputs.version }} -v minimal + dotnet build ./src/Aliencube.AzureFunctions.Extensions.OpenApi -c Release -p:Version=${{ steps.release.outputs.version }} -v minimal + dotnet build ./test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests -c Release - name: Test solution for AppSettings if: steps.release.outputs.module == 'appsettings' @@ -117,12 +127,19 @@ jobs: dir dotnet test ./test/Aliencube.AzureFunctions.Extensions.DependencyInjection.Tests -c Release + - name: Test solution for OpenApi Core + if: steps.release.outputs.module == 'swaggercore' + shell: pwsh + run: | + dir + dotnet test ./test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests -c Release + - name: Test solution for OpenApi if: steps.release.outputs.module == 'swagger' shell: pwsh run: | dir - dotnet test . -c Release + dotnet test ./test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests -c Release - name: List Package for AppSettings if: steps.release.outputs.module == 'appsettings' @@ -157,6 +174,17 @@ jobs: echo "::set-env name=PACKAGE_PATH::$path" echo "::set-env name=PACKAGE_NAME::$name" + - name: List Package for OpenApi Core + if: steps.release.outputs.module == 'swaggercore' + shell: pwsh + run: | + $package = Get-ChildItem -Path ./src/*.OpenApi.Core -Include *.nupkg -Recurse | Where-Object { $_.FullName -like "*${{ steps.release.outputs.version }}*" } + $path = $package[0].FullName + $name = $package[0].Name + + echo "::set-env name=PACKAGE_PATH::$path" + echo "::set-env name=PACKAGE_NAME::$name" + - name: List Package for OpenApi if: steps.release.outputs.module == 'swagger' shell: pwsh diff --git a/.github/workflows/release-cli.yaml b/.github/workflows/release-cli.yaml index 1a40cc1..46ae836 100644 --- a/.github/workflows/release-cli.yaml +++ b/.github/workflows/release-cli.yaml @@ -12,7 +12,7 @@ jobs: matrix: os: [ 'windows-latest' ] node: [ 10 ] - dotnet: [ '3.1.301' ] + dotnet: [ '3.1.302' ] targetFramework: [ 'net461', 'netcoreapp3.1' ] runtime: [ 'win-x64', 'linux-x64', 'osx-x64' ] diff --git a/Aliencube.AzureFunctions.Extensions.sln b/Aliencube.AzureFunctions.Extensions.sln index 77a437d..b8a4f70 100644 --- a/Aliencube.AzureFunctions.Extensions.sln +++ b/Aliencube.AzureFunctions.Extensions.sln @@ -5,6 +5,7 @@ VisualStudioVersion = 16.0.30128.74 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{A1CB6B0E-9E97-4823-910B-735DB69B1931}" ProjectSection(SolutionItems) = preProject + .editorconfig = .editorconfig .gitignore = .gitignore .mailmap = .mailmap appveyor.yml = appveyor.yml @@ -21,20 +22,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aliencube.AzureFunctions.Ex EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aliencube.AzureFunctions.Extensions.DependencyInjection.Tests", "test\Aliencube.AzureFunctions.Extensions.DependencyInjection.Tests\Aliencube.AzureFunctions.Extensions.DependencyInjection.Tests.csproj", "{49C186AD-802E-4C6A-86B1-2092D3FC6660}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aliencube.AzureFunctions.FunctionAppV2.Tests", "test\Aliencube.AzureFunctions.FunctionAppV2.Tests\Aliencube.AzureFunctions.FunctionAppV2.Tests.csproj", "{8C565D1A-D0B4-4901-A592-88862E8C6962}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aliencube.AzureFunctions.Extensions.OpenApi", "src\Aliencube.AzureFunctions.Extensions.OpenApi\Aliencube.AzureFunctions.Extensions.OpenApi.csproj", "{7396872B-B1C3-4788-BC61-04C1F9FF0EB2}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aliencube.AzureFunctions.Extensions.OpenApi.Tests", "test\Aliencube.AzureFunctions.Extensions.OpenApi.Tests\Aliencube.AzureFunctions.Extensions.OpenApi.Tests.csproj", "{E32C7C1A-3D2E-437E-91AE-6FAE33BD068A}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aliencube.AzureFunctions.Extensions.Configuration.Json", "src\Aliencube.AzureFunctions.Extensions.Configuration.Json\Aliencube.AzureFunctions.Extensions.Configuration.Json.csproj", "{E285BCB7-CA1F-41D6-AF9C-514E55831681}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aliencube.AzureFunctions.Extensions.Configuration.AppSettings", "src\Aliencube.AzureFunctions.Extensions.Configuration.AppSettings\Aliencube.AzureFunctions.Extensions.Configuration.AppSettings.csproj", "{64A22A3C-D0C4-4DE9-A8D5-2CEF766EB500}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aliencube.AzureFunctions.Extensions.Configuration.AppSettings.Tests", "test\Aliencube.AzureFunctions.Extensions.Configuration.AppSettings.Tests\Aliencube.AzureFunctions.Extensions.Configuration.AppSettings.Tests.csproj", "{AEF35BD6-EA9A-4159-86F4-49AF7D17A9A8}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aliencube.AzureFunctions.Extensions.OpenApi.CLI", "src\Aliencube.AzureFunctions.Extensions.OpenApi.CLI\Aliencube.AzureFunctions.Extensions.OpenApi.CLI.csproj", "{5C35651B-97D0-4115-81FC-ED8D7ACD71A7}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aliencube.AzureFunctions.Extensions.OpenApi.CLI.Tests", "test\Aliencube.AzureFunctions.Extensions.OpenApi.CLI.Tests\Aliencube.AzureFunctions.Extensions.OpenApi.CLI.Tests.csproj", "{65AED6F0-D27E-4D6E-BA42-AD6EE1338082}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aliencube.AzureFunctions.Extensions.Configuration.Json.Tests", "test\Aliencube.AzureFunctions.Extensions.Configuration.Json.Tests\Aliencube.AzureFunctions.Extensions.Configuration.Json.Tests.csproj", "{F0899514-88DC-4CBF-A392-825BDC094689}" @@ -43,18 +36,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aliencube.AzureFunctions.Ex EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aliencube.AzureFunctions.Extensions.DependencyInjection.Tests.Fakes", "test\Aliencube.AzureFunctions.Extensions.DependencyInjection.Tests.Fakes\Aliencube.AzureFunctions.Extensions.DependencyInjection.Tests.Fakes.csproj", "{A50319A4-2476-4FD2-B066-303A3F7CCF73}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes", "test\Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes\Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes.csproj", "{5C2331B8-EF38-48F3-A060-175530F44F8B}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{66D8DEA8-B477-497F-95BB-E8F9A5BAC352}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aliencube.AzureFunctions.FunctionAppCommon", "samples\Aliencube.AzureFunctions.FunctionAppCommon\Aliencube.AzureFunctions.FunctionAppCommon.csproj", "{4029CCFC-FBA1-4C45-BC78-4D36BC837DFE}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aliencube.AzureFunctions.FunctionAppV1", "samples\Aliencube.AzureFunctions.FunctionAppV1\Aliencube.AzureFunctions.FunctionAppV1.csproj", "{BE1CA502-AA72-4189-92EB-5246648EDF04}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aliencube.AzureFunctions.FunctionAppV2", "samples\Aliencube.AzureFunctions.FunctionAppV2\Aliencube.AzureFunctions.FunctionAppV2.csproj", "{71FDBBD1-78F9-430B-B728-193AFD3E01DA}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aliencube.AzureFunctions.FunctionAppV3", "samples\Aliencube.AzureFunctions.FunctionAppV3\Aliencube.AzureFunctions.FunctionAppV3.csproj", "{9E17D7D4-7BF1-41CC-9823-842A0CC13739}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aliencube.AzureFunctions.FunctionApp.Models", "samples\Aliencube.AzureFunctions.FunctionApp.Models\Aliencube.AzureFunctions.FunctionApp.Models.csproj", "{6ABA1666-BC42-487F-B156-3DC79347BD6B}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aliencube.AzureFunctions.FunctionAppV3Static", "samples\Aliencube.AzureFunctions.FunctionAppV3Static\Aliencube.AzureFunctions.FunctionAppV3Static.csproj", "{C2996131-C3CA-4D3D-8357-C533849792E1}" @@ -83,6 +66,18 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "OpenApiEndpoints", "OpenApi templates\OpenApiEndpints\OpenApiHttpTriggerV1.cs = templates\OpenApiEndpints\OpenApiHttpTriggerV1.cs EndProjectSection EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aliencube.AzureFunctions.Extensions.OpenApi.Core", "src\Aliencube.AzureFunctions.Extensions.OpenApi.Core\Aliencube.AzureFunctions.Extensions.OpenApi.Core.csproj", "{B18937F6-B39F-46BB-BB3C-86C0693993EF}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aliencube.AzureFunctions.Extensions.OpenApi.CLI", "src\Aliencube.AzureFunctions.Extensions.OpenApi.CLI\Aliencube.AzureFunctions.Extensions.OpenApi.CLI.csproj", "{7AD094AA-01D6-4644-B9B6-E555A029D6D7}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes", "test\Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes\Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes.csproj", "{1D1A5ED5-A1A1-4082-ACAF-30079AF31AC6}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests", "test\Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests\Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.csproj", "{968CD847-80D0-4740-92D5-F5553461EC04}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aliencube.AzureFunctions.Extensions.OpenApi", "src\Aliencube.AzureFunctions.Extensions.OpenApi\Aliencube.AzureFunctions.Extensions.OpenApi.csproj", "{D405655F-C8BE-4134-893C-ADB4918B0624}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aliencube.AzureFunctions.Extensions.OpenApi.Tests", "test\Aliencube.AzureFunctions.Extensions.OpenApi.Tests\Aliencube.AzureFunctions.Extensions.OpenApi.Tests.csproj", "{D787694D-B87B-4E11-9455-B5BF9306D8FC}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -97,18 +92,6 @@ Global {49C186AD-802E-4C6A-86B1-2092D3FC6660}.Debug|Any CPU.Build.0 = Debug|Any CPU {49C186AD-802E-4C6A-86B1-2092D3FC6660}.Release|Any CPU.ActiveCfg = Release|Any CPU {49C186AD-802E-4C6A-86B1-2092D3FC6660}.Release|Any CPU.Build.0 = Release|Any CPU - {8C565D1A-D0B4-4901-A592-88862E8C6962}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8C565D1A-D0B4-4901-A592-88862E8C6962}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8C565D1A-D0B4-4901-A592-88862E8C6962}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8C565D1A-D0B4-4901-A592-88862E8C6962}.Release|Any CPU.Build.0 = Release|Any CPU - {7396872B-B1C3-4788-BC61-04C1F9FF0EB2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7396872B-B1C3-4788-BC61-04C1F9FF0EB2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7396872B-B1C3-4788-BC61-04C1F9FF0EB2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7396872B-B1C3-4788-BC61-04C1F9FF0EB2}.Release|Any CPU.Build.0 = Release|Any CPU - {E32C7C1A-3D2E-437E-91AE-6FAE33BD068A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E32C7C1A-3D2E-437E-91AE-6FAE33BD068A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E32C7C1A-3D2E-437E-91AE-6FAE33BD068A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E32C7C1A-3D2E-437E-91AE-6FAE33BD068A}.Release|Any CPU.Build.0 = Release|Any CPU {E285BCB7-CA1F-41D6-AF9C-514E55831681}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {E285BCB7-CA1F-41D6-AF9C-514E55831681}.Debug|Any CPU.Build.0 = Debug|Any CPU {E285BCB7-CA1F-41D6-AF9C-514E55831681}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -121,10 +104,6 @@ Global {AEF35BD6-EA9A-4159-86F4-49AF7D17A9A8}.Debug|Any CPU.Build.0 = Debug|Any CPU {AEF35BD6-EA9A-4159-86F4-49AF7D17A9A8}.Release|Any CPU.ActiveCfg = Release|Any CPU {AEF35BD6-EA9A-4159-86F4-49AF7D17A9A8}.Release|Any CPU.Build.0 = Release|Any CPU - {5C35651B-97D0-4115-81FC-ED8D7ACD71A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5C35651B-97D0-4115-81FC-ED8D7ACD71A7}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5C35651B-97D0-4115-81FC-ED8D7ACD71A7}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5C35651B-97D0-4115-81FC-ED8D7ACD71A7}.Release|Any CPU.Build.0 = Release|Any CPU {65AED6F0-D27E-4D6E-BA42-AD6EE1338082}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {65AED6F0-D27E-4D6E-BA42-AD6EE1338082}.Debug|Any CPU.Build.0 = Debug|Any CPU {65AED6F0-D27E-4D6E-BA42-AD6EE1338082}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -141,26 +120,6 @@ Global {A50319A4-2476-4FD2-B066-303A3F7CCF73}.Debug|Any CPU.Build.0 = Debug|Any CPU {A50319A4-2476-4FD2-B066-303A3F7CCF73}.Release|Any CPU.ActiveCfg = Release|Any CPU {A50319A4-2476-4FD2-B066-303A3F7CCF73}.Release|Any CPU.Build.0 = Release|Any CPU - {5C2331B8-EF38-48F3-A060-175530F44F8B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5C2331B8-EF38-48F3-A060-175530F44F8B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5C2331B8-EF38-48F3-A060-175530F44F8B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5C2331B8-EF38-48F3-A060-175530F44F8B}.Release|Any CPU.Build.0 = Release|Any CPU - {4029CCFC-FBA1-4C45-BC78-4D36BC837DFE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4029CCFC-FBA1-4C45-BC78-4D36BC837DFE}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4029CCFC-FBA1-4C45-BC78-4D36BC837DFE}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4029CCFC-FBA1-4C45-BC78-4D36BC837DFE}.Release|Any CPU.Build.0 = Release|Any CPU - {BE1CA502-AA72-4189-92EB-5246648EDF04}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {BE1CA502-AA72-4189-92EB-5246648EDF04}.Debug|Any CPU.Build.0 = Debug|Any CPU - {BE1CA502-AA72-4189-92EB-5246648EDF04}.Release|Any CPU.ActiveCfg = Release|Any CPU - {BE1CA502-AA72-4189-92EB-5246648EDF04}.Release|Any CPU.Build.0 = Release|Any CPU - {71FDBBD1-78F9-430B-B728-193AFD3E01DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {71FDBBD1-78F9-430B-B728-193AFD3E01DA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {71FDBBD1-78F9-430B-B728-193AFD3E01DA}.Release|Any CPU.ActiveCfg = Release|Any CPU - {71FDBBD1-78F9-430B-B728-193AFD3E01DA}.Release|Any CPU.Build.0 = Release|Any CPU - {9E17D7D4-7BF1-41CC-9823-842A0CC13739}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9E17D7D4-7BF1-41CC-9823-842A0CC13739}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9E17D7D4-7BF1-41CC-9823-842A0CC13739}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9E17D7D4-7BF1-41CC-9823-842A0CC13739}.Release|Any CPU.Build.0 = Release|Any CPU {6ABA1666-BC42-487F-B156-3DC79347BD6B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {6ABA1666-BC42-487F-B156-3DC79347BD6B}.Debug|Any CPU.Build.0 = Debug|Any CPU {6ABA1666-BC42-487F-B156-3DC79347BD6B}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -197,6 +156,30 @@ Global {D6C3806E-2685-4E8D-9F4F-7A93E5270891}.Debug|Any CPU.Build.0 = Debug|Any CPU {D6C3806E-2685-4E8D-9F4F-7A93E5270891}.Release|Any CPU.ActiveCfg = Release|Any CPU {D6C3806E-2685-4E8D-9F4F-7A93E5270891}.Release|Any CPU.Build.0 = Release|Any CPU + {B18937F6-B39F-46BB-BB3C-86C0693993EF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B18937F6-B39F-46BB-BB3C-86C0693993EF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B18937F6-B39F-46BB-BB3C-86C0693993EF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B18937F6-B39F-46BB-BB3C-86C0693993EF}.Release|Any CPU.Build.0 = Release|Any CPU + {7AD094AA-01D6-4644-B9B6-E555A029D6D7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7AD094AA-01D6-4644-B9B6-E555A029D6D7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7AD094AA-01D6-4644-B9B6-E555A029D6D7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7AD094AA-01D6-4644-B9B6-E555A029D6D7}.Release|Any CPU.Build.0 = Release|Any CPU + {1D1A5ED5-A1A1-4082-ACAF-30079AF31AC6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1D1A5ED5-A1A1-4082-ACAF-30079AF31AC6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1D1A5ED5-A1A1-4082-ACAF-30079AF31AC6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1D1A5ED5-A1A1-4082-ACAF-30079AF31AC6}.Release|Any CPU.Build.0 = Release|Any CPU + {968CD847-80D0-4740-92D5-F5553461EC04}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {968CD847-80D0-4740-92D5-F5553461EC04}.Debug|Any CPU.Build.0 = Debug|Any CPU + {968CD847-80D0-4740-92D5-F5553461EC04}.Release|Any CPU.ActiveCfg = Release|Any CPU + {968CD847-80D0-4740-92D5-F5553461EC04}.Release|Any CPU.Build.0 = Release|Any CPU + {D405655F-C8BE-4134-893C-ADB4918B0624}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D405655F-C8BE-4134-893C-ADB4918B0624}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D405655F-C8BE-4134-893C-ADB4918B0624}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D405655F-C8BE-4134-893C-ADB4918B0624}.Release|Any CPU.Build.0 = Release|Any CPU + {D787694D-B87B-4E11-9455-B5BF9306D8FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D787694D-B87B-4E11-9455-B5BF9306D8FC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D787694D-B87B-4E11-9455-B5BF9306D8FC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D787694D-B87B-4E11-9455-B5BF9306D8FC}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -204,23 +187,14 @@ Global GlobalSection(NestedProjects) = preSolution {EE506010-80F2-40CD-BE0E-861474560592} = {810145E0-41CF-4E24-BD9C-E7517498BA29} {49C186AD-802E-4C6A-86B1-2092D3FC6660} = {8B62E3FB-9062-4716-803A-1FA51FCE68BC} - {8C565D1A-D0B4-4901-A592-88862E8C6962} = {8B62E3FB-9062-4716-803A-1FA51FCE68BC} - {7396872B-B1C3-4788-BC61-04C1F9FF0EB2} = {810145E0-41CF-4E24-BD9C-E7517498BA29} - {E32C7C1A-3D2E-437E-91AE-6FAE33BD068A} = {8B62E3FB-9062-4716-803A-1FA51FCE68BC} {E285BCB7-CA1F-41D6-AF9C-514E55831681} = {810145E0-41CF-4E24-BD9C-E7517498BA29} {64A22A3C-D0C4-4DE9-A8D5-2CEF766EB500} = {810145E0-41CF-4E24-BD9C-E7517498BA29} {AEF35BD6-EA9A-4159-86F4-49AF7D17A9A8} = {8B62E3FB-9062-4716-803A-1FA51FCE68BC} - {5C35651B-97D0-4115-81FC-ED8D7ACD71A7} = {810145E0-41CF-4E24-BD9C-E7517498BA29} {65AED6F0-D27E-4D6E-BA42-AD6EE1338082} = {8B62E3FB-9062-4716-803A-1FA51FCE68BC} {F0899514-88DC-4CBF-A392-825BDC094689} = {8B62E3FB-9062-4716-803A-1FA51FCE68BC} {AC89B7CF-0FA5-49EE-97A8-AB39A5F211A8} = {8B62E3FB-9062-4716-803A-1FA51FCE68BC} {A50319A4-2476-4FD2-B066-303A3F7CCF73} = {8B62E3FB-9062-4716-803A-1FA51FCE68BC} - {5C2331B8-EF38-48F3-A060-175530F44F8B} = {8B62E3FB-9062-4716-803A-1FA51FCE68BC} {66D8DEA8-B477-497F-95BB-E8F9A5BAC352} = {810145E0-41CF-4E24-BD9C-E7517498BA29} - {4029CCFC-FBA1-4C45-BC78-4D36BC837DFE} = {66D8DEA8-B477-497F-95BB-E8F9A5BAC352} - {BE1CA502-AA72-4189-92EB-5246648EDF04} = {66D8DEA8-B477-497F-95BB-E8F9A5BAC352} - {71FDBBD1-78F9-430B-B728-193AFD3E01DA} = {66D8DEA8-B477-497F-95BB-E8F9A5BAC352} - {9E17D7D4-7BF1-41CC-9823-842A0CC13739} = {66D8DEA8-B477-497F-95BB-E8F9A5BAC352} {6ABA1666-BC42-487F-B156-3DC79347BD6B} = {66D8DEA8-B477-497F-95BB-E8F9A5BAC352} {C2996131-C3CA-4D3D-8357-C533849792E1} = {66D8DEA8-B477-497F-95BB-E8F9A5BAC352} {B7CF1C77-FE6F-4586-93FE-801671A5EAFD} = {66D8DEA8-B477-497F-95BB-E8F9A5BAC352} @@ -231,6 +205,12 @@ Global {848EDB8F-9C45-462B-A544-EA237774F3BA} = {66D8DEA8-B477-497F-95BB-E8F9A5BAC352} {D6C3806E-2685-4E8D-9F4F-7A93E5270891} = {66D8DEA8-B477-497F-95BB-E8F9A5BAC352} {41695443-A292-4909-89A6-2D9846753164} = {56A43630-87E6-4E94-B24A-859258202578} + {B18937F6-B39F-46BB-BB3C-86C0693993EF} = {810145E0-41CF-4E24-BD9C-E7517498BA29} + {7AD094AA-01D6-4644-B9B6-E555A029D6D7} = {810145E0-41CF-4E24-BD9C-E7517498BA29} + {1D1A5ED5-A1A1-4082-ACAF-30079AF31AC6} = {8B62E3FB-9062-4716-803A-1FA51FCE68BC} + {968CD847-80D0-4740-92D5-F5553461EC04} = {8B62E3FB-9062-4716-803A-1FA51FCE68BC} + {D405655F-C8BE-4134-893C-ADB4918B0624} = {810145E0-41CF-4E24-BD9C-E7517498BA29} + {D787694D-B87B-4E11-9455-B5BF9306D8FC} = {8B62E3FB-9062-4716-803A-1FA51FCE68BC} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {70FEC644-BB3C-4441-AF91-DC694803C8F2} diff --git a/samples/Aliencube.AzureFunctions.FunctionApp.Functions/AddDummyFunction.cs b/samples/Aliencube.AzureFunctions.FunctionApp.Functions/AddDummyFunction.cs new file mode 100644 index 0000000..a5e908d --- /dev/null +++ b/samples/Aliencube.AzureFunctions.FunctionApp.Functions/AddDummyFunction.cs @@ -0,0 +1,54 @@ +#if NET461 +using System; +using System.Net; +using System.Net.Http; +#endif + +using System.Threading.Tasks; + +using Aliencube.AzureFunctions.Extensions.DependencyInjection.Abstractions; +using Aliencube.AzureFunctions.FunctionApp.Services; + +#if !NET461 +using Microsoft.AspNetCore.Mvc; +#endif + +using Microsoft.Extensions.Logging; + +namespace Aliencube.AzureFunctions.FunctionApp.Functions +{ + /// + /// This represents the function entity for sample HTTP trigger. + /// + public class AddDummyFunction : FunctionBase, IAddDummyFunction + { + private readonly IDummyHttpService _service; + + /// + /// Initializes a new instance of the class. + /// + /// instance. + public AddDummyFunction(IDummyHttpService service) + { + this._service = service; + } + + /// + public override async Task InvokeAsync(TInput input, FunctionOptionsBase options = null) + { + this.Log.LogInformation("C# HTTP trigger function processed a request."); + + var content = await this._service.AddDummy().ConfigureAwait(false); +#if NET461 + var req = input as HttpRequestMessage; + var result = req.CreateResponse(HttpStatusCode.OK, content); + + return (TOutput)Convert.ChangeType(result, typeof(TOutput)); +#elif NETSTANDARD2_0 + var result = new OkObjectResult(content); + + return (TOutput)(IActionResult)result; +#endif + } + } +} diff --git a/samples/Aliencube.AzureFunctions.FunctionApp.Functions/GetSamplesFunction.cs b/samples/Aliencube.AzureFunctions.FunctionApp.Functions/GetDummiesFunction.cs similarity index 73% rename from samples/Aliencube.AzureFunctions.FunctionApp.Functions/GetSamplesFunction.cs rename to samples/Aliencube.AzureFunctions.FunctionApp.Functions/GetDummiesFunction.cs index e2e9758..fa2d3a5 100644 --- a/samples/Aliencube.AzureFunctions.FunctionApp.Functions/GetSamplesFunction.cs +++ b/samples/Aliencube.AzureFunctions.FunctionApp.Functions/GetDummiesFunction.cs @@ -1,4 +1,4 @@ -#if NET461 +#if NET461 using System; using System.Net; using System.Net.Http; @@ -20,15 +20,15 @@ namespace Aliencube.AzureFunctions.FunctionApp.Functions /// /// This represents the function entity for sample HTTP trigger. /// - public class GetSamplesFunction : FunctionBase, IGetSamplesFunction + public class GetDummiesFunction : FunctionBase, IGetDummiesFunction { - private readonly ISampleHttpService _service; + private readonly IDummyHttpService _service; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// - /// instance. - public GetSamplesFunction(ISampleHttpService service) + /// instance. + public GetDummiesFunction(IDummyHttpService service) { this._service = service; } @@ -38,7 +38,7 @@ public override async Task InvokeAsync(TInput input, F { this.Log.LogInformation("C# HTTP trigger function processed a request."); - var content = await this._service.GetSamples().ConfigureAwait(false); + var content = await this._service.GetDummies().ConfigureAwait(false); #if NET461 var req = input as HttpRequestMessage; var result = req.CreateResponse(HttpStatusCode.OK, content); diff --git a/samples/Aliencube.AzureFunctions.FunctionApp.Functions/IGetSamplesFunction.cs b/samples/Aliencube.AzureFunctions.FunctionApp.Functions/IAddDummyFunction.cs similarity index 63% rename from samples/Aliencube.AzureFunctions.FunctionApp.Functions/IGetSamplesFunction.cs rename to samples/Aliencube.AzureFunctions.FunctionApp.Functions/IAddDummyFunction.cs index 1f2af68..6407966 100644 --- a/samples/Aliencube.AzureFunctions.FunctionApp.Functions/IGetSamplesFunction.cs +++ b/samples/Aliencube.AzureFunctions.FunctionApp.Functions/IAddDummyFunction.cs @@ -5,9 +5,9 @@ namespace Aliencube.AzureFunctions.FunctionApp.Functions { /// - /// This provides interfaces to . + /// This provides interfaces to . /// - public interface IGetSamplesFunction : IFunction + public interface IAddDummyFunction : IFunction { } } diff --git a/samples/Aliencube.AzureFunctions.FunctionApp.Functions/IGetDummiesFunction.cs b/samples/Aliencube.AzureFunctions.FunctionApp.Functions/IGetDummiesFunction.cs new file mode 100644 index 0000000..861e4d8 --- /dev/null +++ b/samples/Aliencube.AzureFunctions.FunctionApp.Functions/IGetDummiesFunction.cs @@ -0,0 +1,13 @@ +using Aliencube.AzureFunctions.Extensions.DependencyInjection.Abstractions; + +using Microsoft.Extensions.Logging; + +namespace Aliencube.AzureFunctions.FunctionApp.Functions +{ + /// + /// This provides interfaces to . + /// + public interface IGetDummiesFunction : IFunction + { + } +} diff --git a/samples/Aliencube.AzureFunctions.FunctionApp.Models/Aliencube.AzureFunctions.FunctionApp.Models.csproj b/samples/Aliencube.AzureFunctions.FunctionApp.Models/Aliencube.AzureFunctions.FunctionApp.Models.csproj index f588022..98f847d 100644 --- a/samples/Aliencube.AzureFunctions.FunctionApp.Models/Aliencube.AzureFunctions.FunctionApp.Models.csproj +++ b/samples/Aliencube.AzureFunctions.FunctionApp.Models/Aliencube.AzureFunctions.FunctionApp.Models.csproj @@ -1,11 +1,11 @@ - + net461;netstandard2.0 - + diff --git a/samples/Aliencube.AzureFunctions.FunctionApp.Models/DummyArrayResponseModel.cs b/samples/Aliencube.AzureFunctions.FunctionApp.Models/DummyArrayResponseModel.cs new file mode 100644 index 0000000..22c1f2f --- /dev/null +++ b/samples/Aliencube.AzureFunctions.FunctionApp.Models/DummyArrayResponseModel.cs @@ -0,0 +1,12 @@ +using Newtonsoft.Json; + +namespace Aliencube.AzureFunctions.FunctionApp.Models +{ + public class DummyArrayResponseModel + { + public string Id { get; set; } + + [JsonRequired] + public string JsonRequiredValue { get; set; } + } +} diff --git a/samples/Aliencube.AzureFunctions.FunctionApp.Models/DummyDictionaryResponseModel.cs b/samples/Aliencube.AzureFunctions.FunctionApp.Models/DummyDictionaryResponseModel.cs new file mode 100644 index 0000000..d660322 --- /dev/null +++ b/samples/Aliencube.AzureFunctions.FunctionApp.Models/DummyDictionaryResponseModel.cs @@ -0,0 +1,14 @@ +using System; + +using Newtonsoft.Json; + +namespace Aliencube.AzureFunctions.FunctionApp.Models +{ + public class DummyDictionaryResponseModel + { + public Guid? Id { get; set; } + + [JsonRequired] + public string JsonRequiredValue { get; set; } + } +} diff --git a/samples/Aliencube.AzureFunctions.FunctionApp.Models/DummyRecursiveResponseModel.cs b/samples/Aliencube.AzureFunctions.FunctionApp.Models/DummyRecursiveResponseModel.cs new file mode 100644 index 0000000..93f7d36 --- /dev/null +++ b/samples/Aliencube.AzureFunctions.FunctionApp.Models/DummyRecursiveResponseModel.cs @@ -0,0 +1,9 @@ +namespace Aliencube.AzureFunctions.FunctionApp.Models +{ + public class DummyRecursiveResponseModel + { + public string Id { get; set; } + + public DummyRecursiveResponseModel RecursiveValue { get; set; } + } +} diff --git a/samples/Aliencube.AzureFunctions.FunctionApp.Models/DummyRequestModel.cs b/samples/Aliencube.AzureFunctions.FunctionApp.Models/DummyRequestModel.cs new file mode 100644 index 0000000..c9d2590 --- /dev/null +++ b/samples/Aliencube.AzureFunctions.FunctionApp.Models/DummyRequestModel.cs @@ -0,0 +1,37 @@ +using System; + +namespace Aliencube.AzureFunctions.FunctionApp.Models +{ + public class DummyRequestModel + { + public Guid Id { get; set; } + + public short ShortValue { get; set; } + + public int IntValue { get; set; } + + public long LongValue { get; set; } + + public float SingleValue { get; set; } + + public double DoubleValue { get; set; } + + public decimal DecimalValue { get; set; } + + public int? NullableIntValue { get; set; } + + public bool BoolValue { get; set; } + + public ShortEnum ShortEnumValue { get; set; } + + public IntEnum IntEnumValue { get; set; } + + public LongEnum LongEnumValue { get; set; } + + public StringEnum StringEnumValue { get; set; } + + public DateTime DateTimeValue { get; set; } + + public DateTimeOffset DateTimeOffsetValue { get; set; } + } +} diff --git a/samples/Aliencube.AzureFunctions.FunctionApp.Models/DummyResponseModel.cs b/samples/Aliencube.AzureFunctions.FunctionApp.Models/DummyResponseModel.cs new file mode 100644 index 0000000..e5cc420 --- /dev/null +++ b/samples/Aliencube.AzureFunctions.FunctionApp.Models/DummyResponseModel.cs @@ -0,0 +1,50 @@ +using System.Collections.Generic; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums; + +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Aliencube.AzureFunctions.FunctionApp.Models +{ + public class DummyResponseModel + { + public DummySubResponseModel SubObjectValue { get; set; } + + public DummyRecursiveResponseModel RecursiveObjectValue { get; set; } + + public IDictionary DictionaryStringValue { get; set; } + + public Dictionary DictionaryIntValue { get; set; } + + public Dictionary DictionaryObjectValue { get; set; } + + public IList ListStringValue { get; set; } + + public List ListIntValue { get; set; } + + public List ListObjectValue { get; set; } + + public DummyArrayResponseModel[] ArrayObjectValue { get; set; } + + public JObject JObjectValue { get; set; } + + public JToken JTokenValue { get; set; } + + [JsonProperty("CapitalisedJsonPropertyValue")] + public string JsonPropertyValue { get; set; } + + [JsonIgnore] + public string JsonIgnoreValue { get; set; } + + [JsonProperty("CapitalisedJsonPropertyRequiredValue", Required = Required.DisallowNull)] + public string JsonPropertyRequiredValue { get; set; } = "hello world"; + + [JsonRequired] + public string JsonRequiredValue { get; set; } = "lorem ipsum"; + + [OpenApiSchemaVisibility(OpenApiVisibilityType.Advanced)] + public string OpenApiSchemaVisibilityValue { get; set; } + } +} diff --git a/samples/Aliencube.AzureFunctions.FunctionApp.Models/DummySubResponseModel.cs b/samples/Aliencube.AzureFunctions.FunctionApp.Models/DummySubResponseModel.cs new file mode 100644 index 0000000..0c65197 --- /dev/null +++ b/samples/Aliencube.AzureFunctions.FunctionApp.Models/DummySubResponseModel.cs @@ -0,0 +1,12 @@ +using Newtonsoft.Json; + +namespace Aliencube.AzureFunctions.FunctionApp.Models +{ + public class DummySubResponseModel + { + public int Id { get; set; } + + [JsonProperty("CapitalisedJsonRequiredValue", Required = Required.Always)] + public string JsonRequiredValue { get; set; } + } +} diff --git a/samples/Aliencube.AzureFunctions.FunctionApp.Models/IntEnum.cs b/samples/Aliencube.AzureFunctions.FunctionApp.Models/IntEnum.cs new file mode 100644 index 0000000..5952588 --- /dev/null +++ b/samples/Aliencube.AzureFunctions.FunctionApp.Models/IntEnum.cs @@ -0,0 +1,8 @@ +namespace Aliencube.AzureFunctions.FunctionApp.Models +{ + public enum IntEnum + { + Value1, + Value2 + } +} diff --git a/samples/Aliencube.AzureFunctions.FunctionApp.Models/LongEnum.cs b/samples/Aliencube.AzureFunctions.FunctionApp.Models/LongEnum.cs new file mode 100644 index 0000000..51a95eb --- /dev/null +++ b/samples/Aliencube.AzureFunctions.FunctionApp.Models/LongEnum.cs @@ -0,0 +1,8 @@ +namespace Aliencube.AzureFunctions.FunctionApp.Models +{ + public enum LongEnum : long + { + Value1, + Value2 + } +} diff --git a/samples/Aliencube.AzureFunctions.FunctionApp.Models/OrderStatus.cs b/samples/Aliencube.AzureFunctions.FunctionApp.Models/OrderStatus.cs index 88bb401..b564278 100644 --- a/samples/Aliencube.AzureFunctions.FunctionApp.Models/OrderStatus.cs +++ b/samples/Aliencube.AzureFunctions.FunctionApp.Models/OrderStatus.cs @@ -1,4 +1,4 @@ -using Aliencube.AzureFunctions.Extensions.OpenApi.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; using Newtonsoft.Json; using Newtonsoft.Json.Converters; diff --git a/samples/Aliencube.AzureFunctions.FunctionApp.Models/PetStatus.cs b/samples/Aliencube.AzureFunctions.FunctionApp.Models/PetStatus.cs index a8fb7f3..da1607c 100644 --- a/samples/Aliencube.AzureFunctions.FunctionApp.Models/PetStatus.cs +++ b/samples/Aliencube.AzureFunctions.FunctionApp.Models/PetStatus.cs @@ -1,4 +1,4 @@ -using Aliencube.AzureFunctions.Extensions.OpenApi.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; using Newtonsoft.Json; using Newtonsoft.Json.Converters; diff --git a/samples/Aliencube.AzureFunctions.FunctionApp.Models/SampleGenericResponseModel.cs b/samples/Aliencube.AzureFunctions.FunctionApp.Models/SampleGenericResponseModel.cs deleted file mode 100644 index edb2d5f..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionApp.Models/SampleGenericResponseModel.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System.Collections.Generic; - -namespace Aliencube.AzureFunctions.FunctionApp.Models -{ - /// - /// This represents the generic model entity. - /// - /// Type of item. - public class SampleGenericResponseModel - { - /// - /// Gets or sets the page. - /// - public int Page { get; set; } - - /// - /// Gets or sets the list of items. - /// - public List Items { get; set; } - - /// - /// Gets or sets the collection of items. - /// - public Dictionary Collection { get; set; } - - /// - /// Gets or sets the item. - /// - public T Item { get; set; } - } -} \ No newline at end of file diff --git a/samples/Aliencube.AzureFunctions.FunctionApp.Models/SampleItemModel.cs b/samples/Aliencube.AzureFunctions.FunctionApp.Models/SampleItemModel.cs deleted file mode 100644 index 53ea82e..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionApp.Models/SampleItemModel.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Newtonsoft.Json; - -namespace Aliencube.AzureFunctions.FunctionApp.Models -{ - /// - /// This represents the item model of a collection. - /// - public class SampleItemModel - { - /// - /// Gets or sets the first name. - /// - [JsonProperty("firstName")] - public string FirstName { get; set; } - - /// - /// Gets or sets the last name. - /// - [JsonProperty("lastName")] - public string LastName { get; set; } - } -} \ No newline at end of file diff --git a/samples/Aliencube.AzureFunctions.FunctionApp.Models/SampleRequestModel.cs b/samples/Aliencube.AzureFunctions.FunctionApp.Models/SampleRequestModel.cs deleted file mode 100644 index e320502..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionApp.Models/SampleRequestModel.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Aliencube.AzureFunctions.FunctionApp.Models -{ - /// - /// This represents the model entity for sample request. - /// - public class SampleRequestModel - { - /// - /// Gets or sets the Id. - /// - public string Id { get; set; } - } -} \ No newline at end of file diff --git a/samples/Aliencube.AzureFunctions.FunctionApp.Models/SampleResponseModel.cs b/samples/Aliencube.AzureFunctions.FunctionApp.Models/SampleResponseModel.cs deleted file mode 100644 index 8edff9f..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionApp.Models/SampleResponseModel.cs +++ /dev/null @@ -1,74 +0,0 @@ -using System; -using System.Collections.Generic; - -using Aliencube.AzureFunctions.Extensions.OpenApi.Attributes; -using Aliencube.AzureFunctions.Extensions.OpenApi.Enums; - -using Newtonsoft.Json; - -namespace Aliencube.AzureFunctions.FunctionApp.Models -{ - /// - /// This represents the model entity for sample response. - /// - public class SampleResponseModel - { - /// - /// Gets or sets the Id. - /// - public Guid Id { get; set; } - - /// - /// Gets or sets the name. - /// - [OpenApiSchemaVisibility(OpenApiVisibilityType.Advanced)] - public string Name { get; set; } - - /// - /// Gets or sets the description. - /// - [JsonIgnore] - public string Description { get; set; } - - /// - /// Gets or sets the instance. - /// - [JsonProperty("subModel")] - public SubSampleResponseModel Sub { get; set; } - - /// - /// Gets or sets the dictionary object. - /// - public Dictionary Collection { get; set; } = new Dictionary(); - - /// - /// Gets or sets the list objects 1. - /// - public List Items1 { get; set; } = new List(); - - /// - /// Gets or sets the list of objects 2. - /// - public int[] Items2 { get; set; } = new List().ToArray(); - - /// - /// Gets or sets the date time value. - /// - public DateTime DateTimeValue { get; set; } - - /// - /// Gets or sets the date time offset value. - /// - public DateTimeOffset DateTimeOffsetValue { get; set; } - - /// - /// Gets or sets an enum value. - /// - public StringEnum EnumValueAsString { get; set; } - - /// - /// Gets or sets an enum value. - /// - public NumericEnum EnumValueAsNumber { get; set; } - } -} \ No newline at end of file diff --git a/samples/Aliencube.AzureFunctions.FunctionApp.Models/ShortEnum.cs b/samples/Aliencube.AzureFunctions.FunctionApp.Models/ShortEnum.cs new file mode 100644 index 0000000..703689c --- /dev/null +++ b/samples/Aliencube.AzureFunctions.FunctionApp.Models/ShortEnum.cs @@ -0,0 +1,8 @@ +namespace Aliencube.AzureFunctions.FunctionApp.Models +{ + public enum ShortEnum : short + { + Value1, + Value2 + } +} diff --git a/samples/Aliencube.AzureFunctions.FunctionApp.Models/SubSampleResponseModel.cs b/samples/Aliencube.AzureFunctions.FunctionApp.Models/SubSampleResponseModel.cs deleted file mode 100644 index 8f7661d..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionApp.Models/SubSampleResponseModel.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace Aliencube.AzureFunctions.FunctionApp.Models -{ - /// - /// This represents the sub model entity for sample response - /// - public class SubSampleResponseModel - { - /// - /// Gets or sets the key. - /// - public string Key { get; set; } - - /// - /// Gets or sets the value. - /// - public int Value { get; set; } - } -} \ No newline at end of file diff --git a/samples/Aliencube.AzureFunctions.FunctionApp.Services/DummyHttpService.cs b/samples/Aliencube.AzureFunctions.FunctionApp.Services/DummyHttpService.cs new file mode 100644 index 0000000..d7b3068 --- /dev/null +++ b/samples/Aliencube.AzureFunctions.FunctionApp.Services/DummyHttpService.cs @@ -0,0 +1,31 @@ +using System.Collections.Generic; +using System.Threading.Tasks; + +using Aliencube.AzureFunctions.FunctionApp.Models; + +namespace Aliencube.AzureFunctions.FunctionApp.Services +{ + /// + /// This represents the service entity for the sample HTTP trigger. + /// + public class DummyHttpService : IDummyHttpService + { + /// + public async Task> GetDummies() + { + var result = new List() + { + new DummyResponseModel(), + }; + + return await Task.FromResult(result).ConfigureAwait(false); + } + + public async Task AddDummy() + { + var result = new DummyResponseModel(); + + return await Task.FromResult(result).ConfigureAwait(false); + } + } +} diff --git a/samples/Aliencube.AzureFunctions.FunctionApp.Services/IDummyHttpService.cs b/samples/Aliencube.AzureFunctions.FunctionApp.Services/IDummyHttpService.cs new file mode 100644 index 0000000..fd1656f --- /dev/null +++ b/samples/Aliencube.AzureFunctions.FunctionApp.Services/IDummyHttpService.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; +using System.Threading.Tasks; + +using Aliencube.AzureFunctions.FunctionApp.Models; + +namespace Aliencube.AzureFunctions.FunctionApp.Services +{ + /// + /// This provides interfaces to . + /// + public interface IDummyHttpService + { + /// + /// Gets the list of objects. + /// + /// Returns the list of objects. + Task> GetDummies(); + + /// + /// Adds dummy data. + /// + /// Returns the instance. + Task AddDummy(); + } +} diff --git a/samples/Aliencube.AzureFunctions.FunctionApp.Services/ISampleHttpService.cs b/samples/Aliencube.AzureFunctions.FunctionApp.Services/ISampleHttpService.cs deleted file mode 100644 index e95e428..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionApp.Services/ISampleHttpService.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System.Collections.Generic; -using System.Threading.Tasks; - -using Aliencube.AzureFunctions.FunctionApp.Models; - -namespace Aliencube.AzureFunctions.FunctionApp.Services -{ - /// - /// This provides interfaces to . - /// - public interface ISampleHttpService - { - /// - /// Gets the list of objects. - /// - /// Returns the list of objects. - Task> GetSamples(); - } -} diff --git a/samples/Aliencube.AzureFunctions.FunctionApp.Services/SampleHttpService.cs b/samples/Aliencube.AzureFunctions.FunctionApp.Services/SampleHttpService.cs deleted file mode 100644 index 36c5cfe..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionApp.Services/SampleHttpService.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.Collections.Generic; -using System.Threading.Tasks; - -using Aliencube.AzureFunctions.FunctionApp.Models; - -namespace Aliencube.AzureFunctions.FunctionApp.Services -{ - /// - /// This represents the service entity for the sample HTTP trigger. - /// - public class SampleHttpService : ISampleHttpService - { - /// - public async Task> GetSamples() - { - var result = new List() - { - new SampleResponseModel(), - }; - - return await Task.FromResult(result).ConfigureAwait(false); - } - } -} diff --git a/samples/Aliencube.AzureFunctions.FunctionAppCommon/Aliencube.AzureFunctions.FunctionAppCommon.csproj b/samples/Aliencube.AzureFunctions.FunctionAppCommon/Aliencube.AzureFunctions.FunctionAppCommon.csproj deleted file mode 100644 index 57416c3..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionAppCommon/Aliencube.AzureFunctions.FunctionAppCommon.csproj +++ /dev/null @@ -1,13 +0,0 @@ - - - - net461;netstandard2.0 - - - - - - - - - diff --git a/samples/Aliencube.AzureFunctions.FunctionAppCommon/Configurations/AppSettings.cs b/samples/Aliencube.AzureFunctions.FunctionAppCommon/Configurations/AppSettings.cs deleted file mode 100644 index 3b226ca..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionAppCommon/Configurations/AppSettings.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Aliencube.AzureFunctions.Extensions.OpenApi.Configurations; - -namespace Aliencube.AzureFunctions.FunctionAppCommon.Configurations -{ - /// - /// This represents the settings entity from the configurations. - /// - public class AppSettings : OpenApiAppSettingsBase - { - /// - /// Initializes a new instance of the class. - /// - public AppSettings() - : base() - { - } - } -} \ No newline at end of file diff --git a/samples/Aliencube.AzureFunctions.FunctionAppCommon/Dependencies/IMyDependency.cs b/samples/Aliencube.AzureFunctions.FunctionAppCommon/Dependencies/IMyDependency.cs deleted file mode 100644 index 0894d90..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionAppCommon/Dependencies/IMyDependency.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Aliencube.AzureFunctions.FunctionAppCommon.Dependencies -{ - public interface IMyDependency - { - string Name { get; set; } - } -} \ No newline at end of file diff --git a/samples/Aliencube.AzureFunctions.FunctionAppCommon/Dependencies/MyDependency.cs b/samples/Aliencube.AzureFunctions.FunctionAppCommon/Dependencies/MyDependency.cs deleted file mode 100644 index 04dd091..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionAppCommon/Dependencies/MyDependency.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Aliencube.AzureFunctions.FunctionAppCommon.Dependencies -{ - public class MyDependency : IMyDependency - { - public string Name { get; set; } - } -} \ No newline at end of file diff --git a/samples/Aliencube.AzureFunctions.FunctionAppCommon/Functions/FunctionOptions/RenderOpeApiDocumentFunctionOptions.cs b/samples/Aliencube.AzureFunctions.FunctionAppCommon/Functions/FunctionOptions/RenderOpeApiDocumentFunctionOptions.cs deleted file mode 100644 index fa97395..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionAppCommon/Functions/FunctionOptions/RenderOpeApiDocumentFunctionOptions.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System; -using System.Reflection; - -using Aliencube.AzureFunctions.Extensions.DependencyInjection.Abstractions; - -using Microsoft.OpenApi; - -namespace Aliencube.AzureFunctions.FunctionAppCommon.Functions.FunctionOptions -{ - /// - /// This represents the options entity for . - /// - public class RenderOpeApiDocumentFunctionOptions : FunctionOptionsBase - { - /// - /// Initializes a new instance of the class. - /// - /// Open API version. This MUST be either "v2" or "v3". - /// Open API document format. This MUST be either "json" or "yaml". - /// Function app assembly. - public RenderOpeApiDocumentFunctionOptions(string version, string format, Assembly assembly) - { - this.Version = this.GetVersion(version); - this.Format = this.GetFormat(format); - this.Assembly = assembly ?? throw new ArgumentNullException(nameof(assembly)); - } - - /// - /// Gets or sets the value. - /// - public OpenApiSpecVersion Version { get; set; } - - /// - /// Gets or sets the value. - /// - public OpenApiFormat Format { get; set; } - - /// - /// Gets or sets the instance. - /// - public Assembly Assembly { get; set; } - - private OpenApiSpecVersion GetVersion(string version) - { - if (string.IsNullOrWhiteSpace(version)) - { - throw new ArgumentNullException(nameof(version)); - } - - if (version.Equals("v2", StringComparison.CurrentCultureIgnoreCase)) - { - return OpenApiSpecVersion.OpenApi2_0; - } - - if (version.Equals("v3", StringComparison.CurrentCultureIgnoreCase)) - { - return OpenApiSpecVersion.OpenApi3_0; - } - - throw new InvalidOperationException("Invalid Open API version"); - } - - private OpenApiFormat GetFormat(string format) - { - if (string.IsNullOrWhiteSpace(format)) - { - throw new ArgumentNullException(nameof(format)); - } - - return Enum.TryParse(format, true, out OpenApiFormat result) - ? result - : throw new InvalidOperationException("Invalid Open API format"); - } - } -} \ No newline at end of file diff --git a/samples/Aliencube.AzureFunctions.FunctionAppCommon/Functions/FunctionOptions/RenderSwaggerUIFunctionOptions.cs b/samples/Aliencube.AzureFunctions.FunctionAppCommon/Functions/FunctionOptions/RenderSwaggerUIFunctionOptions.cs deleted file mode 100644 index bf7e67e..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionAppCommon/Functions/FunctionOptions/RenderSwaggerUIFunctionOptions.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; - -using Aliencube.AzureFunctions.Extensions.DependencyInjection.Abstractions; - -namespace Aliencube.AzureFunctions.FunctionAppCommon.Functions.FunctionOptions -{ - /// - /// This represents the options entity for . - /// - public class RenderSwaggerUIFunctionOptions : FunctionOptionsBase - { - /// - /// Initializes a new instance of the class. - /// - /// Function app endpoint for Swagger document. - public RenderSwaggerUIFunctionOptions(string endpoint = "swagger.json") - { - this.Endpoint = endpoint ?? throw new ArgumentNullException(nameof(endpoint)); - } - - /// - /// Gets or sets the endpoint of the Swagger document. - /// - public string Endpoint { get; set; } - } -} \ No newline at end of file diff --git a/samples/Aliencube.AzureFunctions.FunctionAppCommon/Functions/FunctionOptions/SampleTimerFunctionOptions.cs b/samples/Aliencube.AzureFunctions.FunctionAppCommon/Functions/FunctionOptions/SampleTimerFunctionOptions.cs deleted file mode 100644 index 19cddb0..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionAppCommon/Functions/FunctionOptions/SampleTimerFunctionOptions.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Aliencube.AzureFunctions.Extensions.DependencyInjection.Abstractions; - -using Microsoft.Azure.WebJobs; - -namespace Aliencube.AzureFunctions.FunctionAppCommon.Functions.FunctionOptions -{ - public class SampleTimerFunctionOptions : FunctionOptionsBase - { - public IAsyncCollector Collector { get; set; } - } -} \ No newline at end of file diff --git a/samples/Aliencube.AzureFunctions.FunctionAppCommon/Functions/IRenderOpeApiDocumentFunction.cs b/samples/Aliencube.AzureFunctions.FunctionAppCommon/Functions/IRenderOpeApiDocumentFunction.cs deleted file mode 100644 index 086db3c..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionAppCommon/Functions/IRenderOpeApiDocumentFunction.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Aliencube.AzureFunctions.Extensions.DependencyInjection.Abstractions; - -using Microsoft.Extensions.Logging; - -namespace Aliencube.AzureFunctions.FunctionAppCommon.Functions -{ - /// - /// This provides interfaces to the class. - /// - public interface IRenderOpeApiDocumentFunction : IFunction - { - } -} \ No newline at end of file diff --git a/samples/Aliencube.AzureFunctions.FunctionAppCommon/Functions/IRenderSwaggerUIFunction.cs b/samples/Aliencube.AzureFunctions.FunctionAppCommon/Functions/IRenderSwaggerUIFunction.cs deleted file mode 100644 index 7f5296d..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionAppCommon/Functions/IRenderSwaggerUIFunction.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Aliencube.AzureFunctions.Extensions.DependencyInjection.Abstractions; - -using Microsoft.Extensions.Logging; - -namespace Aliencube.AzureFunctions.FunctionAppCommon.Functions -{ - /// - /// This provides interfaces to the class. - /// - public interface IRenderSwaggerUIFunction : IFunction - { - } -} \ No newline at end of file diff --git a/samples/Aliencube.AzureFunctions.FunctionAppCommon/Functions/ISampleHttpFunction.cs b/samples/Aliencube.AzureFunctions.FunctionAppCommon/Functions/ISampleHttpFunction.cs deleted file mode 100644 index 85a25f7..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionAppCommon/Functions/ISampleHttpFunction.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Aliencube.AzureFunctions.Extensions.DependencyInjection.Abstractions; - -using Microsoft.Extensions.Logging; - -namespace Aliencube.AzureFunctions.FunctionAppCommon.Functions -{ - public interface ISampleHttpFunction : IFunction - { - } -} \ No newline at end of file diff --git a/samples/Aliencube.AzureFunctions.FunctionAppCommon/Functions/ISampleTimerFunction.cs b/samples/Aliencube.AzureFunctions.FunctionAppCommon/Functions/ISampleTimerFunction.cs deleted file mode 100644 index 275d54a..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionAppCommon/Functions/ISampleTimerFunction.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Aliencube.AzureFunctions.Extensions.DependencyInjection.Abstractions; - -using Microsoft.Extensions.Logging; - -namespace Aliencube.AzureFunctions.FunctionAppCommon.Functions -{ - public interface ISampleTimerFunction : IFunction - { - } -} \ No newline at end of file diff --git a/samples/Aliencube.AzureFunctions.FunctionAppCommon/Functions/RenderOpeApiDocumentFunction.cs b/samples/Aliencube.AzureFunctions.FunctionAppCommon/Functions/RenderOpeApiDocumentFunction.cs deleted file mode 100644 index 7327774..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionAppCommon/Functions/RenderOpeApiDocumentFunction.cs +++ /dev/null @@ -1,90 +0,0 @@ -#if NET461 -using System; -#endif - -using System.Net; - -#if NET461 -using System.Net.Http; -#endif - -using System.Reflection; - -#if NET461 -using System.Text; -#endif - -using System.Threading.Tasks; - -using Aliencube.AzureFunctions.Extensions.DependencyInjection.Abstractions; -using Aliencube.AzureFunctions.Extensions.OpenApi.Abstractions; -using Aliencube.AzureFunctions.Extensions.OpenApi.Extensions; -using Aliencube.AzureFunctions.FunctionAppCommon.Configurations; -using Aliencube.AzureFunctions.FunctionAppCommon.Functions.FunctionOptions; - -#if NETSTANDARD2_0 -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -#endif - -using Microsoft.Extensions.Logging; - -namespace Aliencube.AzureFunctions.FunctionAppCommon.Functions -{ - /// - /// This represents the function entity to render Open API document. - /// - public class RenderOpeApiDocumentFunction : FunctionBase, IRenderOpeApiDocumentFunction - { - private readonly AppSettings _settings; - private readonly IDocument _document; - - /// - /// Initializes a new instance of the class. - /// - /// instance. - /// instance. - public RenderOpeApiDocumentFunction(AppSettings settings, IDocument document) - { - this._settings = settings; - this._document = document; - } - - /// - public override async Task InvokeAsync(TInput input, FunctionOptionsBase options = null) - { - this.Log.LogInformation("C# HTTP trigger function processed a request."); -#if NET461 - var req = input as HttpRequestMessage; -#elif NETSTANDARD2_0 - var req = input as HttpRequest; -#endif - var opt = options as RenderOpeApiDocumentFunctionOptions; - - var contentType = opt.Format.GetContentType(); - var result = await this._document - .InitialiseDocument() - .AddMetadata(this._settings.OpenApiInfo) - .AddServer(req, this._settings.HttpSettings.RoutePrefix) - .Build(opt.Assembly) - .RenderAsync(opt.Version, opt.Format) - .ConfigureAwait(false); - -#if NET461 - var content = new StringContent(result, Encoding.UTF8, contentType); - var response = new HttpResponseMessage(HttpStatusCode.OK) { Content = content }; - - return (TOutput)Convert.ChangeType(response, typeof(TOutput)); -#elif NETSTANDARD2_0 - var content = new ContentResult() - { - Content = result, - ContentType = contentType, - StatusCode = (int)HttpStatusCode.OK - }; - - return (TOutput)(IActionResult)content; -#endif - } - } -} \ No newline at end of file diff --git a/samples/Aliencube.AzureFunctions.FunctionAppCommon/Functions/RenderSwaggerUIFunction.cs b/samples/Aliencube.AzureFunctions.FunctionAppCommon/Functions/RenderSwaggerUIFunction.cs deleted file mode 100644 index 0d5e44e..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionAppCommon/Functions/RenderSwaggerUIFunction.cs +++ /dev/null @@ -1,85 +0,0 @@ -#if NET461 -using System; -#endif - -using System.Net; - -#if NET461 -using System.Net.Http; -#endif - -#if NET461 -using System.Text; -#endif - -using System.Threading.Tasks; - -using Aliencube.AzureFunctions.Extensions.DependencyInjection.Abstractions; -using Aliencube.AzureFunctions.Extensions.OpenApi.Abstractions; -using Aliencube.AzureFunctions.Extensions.OpenApi.Extensions; -using Aliencube.AzureFunctions.FunctionAppCommon.Configurations; -using Aliencube.AzureFunctions.FunctionAppCommon.Functions.FunctionOptions; - -#if NETSTANDARD2_0 -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -#endif - -using Microsoft.Extensions.Logging; - -namespace Aliencube.AzureFunctions.FunctionAppCommon.Functions -{ - /// - /// This represents the function entity to render Swagger UI. - /// - public class RenderSwaggerUIFunction : FunctionBase, IRenderSwaggerUIFunction - { - private readonly AppSettings _settings; - private readonly ISwaggerUI _ui; - - /// - /// Initializes a new instance of the class. - /// - /// instance. - /// instance. - public RenderSwaggerUIFunction(AppSettings settings, ISwaggerUI ui) - { - this._settings = settings; - this._ui = ui; - } - - /// - public override async Task InvokeAsync(TInput input, FunctionOptionsBase options = null) - { - this.Log.LogInformation("C# HTTP trigger function processed a request."); -#if NET461 - var req = input as HttpRequestMessage; -#elif NETSTANDARD2_0 - var req = input as HttpRequest; -#endif - var opt = options as RenderSwaggerUIFunctionOptions; - - var result = await this._ui - .AddMetadata(this._settings.OpenApiInfo) - .AddServer(req, this._settings.HttpSettings.RoutePrefix) - .BuildAsync() - .RenderAsync(opt.Endpoint, this._settings.SwaggerAuthKey) - .ConfigureAwait(false); -#if NET461 - var content = new StringContent(result, Encoding.UTF8, "text/html"); - var response = new HttpResponseMessage(HttpStatusCode.OK) { Content = content }; - - return (TOutput)Convert.ChangeType(response, typeof(TOutput)); -#elif NETSTANDARD2_0 - var content = new ContentResult() - { - Content = result, - ContentType = "text/html", - StatusCode = (int)HttpStatusCode.OK - }; - - return (TOutput)(IActionResult)content; -#endif - } - } -} \ No newline at end of file diff --git a/samples/Aliencube.AzureFunctions.FunctionAppCommon/Functions/SampleHttpFunction.cs b/samples/Aliencube.AzureFunctions.FunctionAppCommon/Functions/SampleHttpFunction.cs deleted file mode 100644 index 00e3a02..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionAppCommon/Functions/SampleHttpFunction.cs +++ /dev/null @@ -1,108 +0,0 @@ -using System; - -#if NETSTANDARD2_0 -using System.IO; -#endif - -using System.Linq; -using System.Net; - -#if NET461 -using System.Net.Http; -using System.Text; -#endif - -using System.Threading.Tasks; - -using Aliencube.AzureFunctions.Extensions.DependencyInjection.Abstractions; -using Aliencube.AzureFunctions.FunctionAppCommon.Dependencies; -using Aliencube.AzureFunctions.FunctionAppCommon.Models; - -#if NETSTANDARD2_0 -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -#endif - -using Microsoft.Extensions.Logging; - -using Newtonsoft.Json; - -namespace Aliencube.AzureFunctions.FunctionAppCommon.Functions -{ - /// - /// This represents the function entity for sample HTTP trigger. - /// - public class SampleHttpFunction : FunctionBase, ISampleHttpFunction - { - private readonly IMyDependency _dependency; - - /// - /// Initializes a new instance of the class. - /// - /// instance. - public SampleHttpFunction(IMyDependency dependency) - { - this._dependency = dependency; - } - - /// - public override async Task InvokeAsync(TInput input, FunctionOptionsBase options = null) - { - this.Log.LogInformation("C# HTTP trigger function processed a request."); -#if NET461 - var req = input as HttpRequestMessage; -#elif NETSTANDARD2_0 - var req = input as HttpRequest; -#endif - var request = (SampleRequestModel)null; - -#if NET461 - var serialised = await req.Content.ReadAsStringAsync().ConfigureAwait(false); -#elif NETSTANDARD2_0 - var serialised = await new StreamReader(req.Body).ReadToEndAsync().ConfigureAwait(false); -#endif - if (!string.IsNullOrWhiteSpace(serialised)) - { - request = JsonConvert.DeserializeObject(serialised); - } - -#if NET461 - string name = req.GetQueryNameValuePairs() - .SingleOrDefault(p => p.Key.Equals("name", StringComparison.CurrentCultureIgnoreCase)) - .Value; -#elif NETSTANDARD2_0 - string name = req.Query["name"]; -#endif - - this._dependency.Name = name; - - this.Log.LogInformation($"input: {this._dependency.Name}"); - - var result = new SampleResponseModel() - { - Id = request == null ? Guid.NewGuid() : Guid.Parse(request.Id), - Name = string.IsNullOrWhiteSpace(name) ? "Sample" : name, - Description = "Ignored", - Sub = new SubSampleResponseModel() { Value = int.MaxValue }, - Collection = { { "hello", "world" } }, - Items1 = { { int.MinValue } }, - Items2 = new[] { int.MinValue }.ToArray() - }; -#if NET461 - var content = new StringContent(JsonConvert.SerializeObject(result), Encoding.UTF8, "application/json"); - var response = new HttpResponseMessage(HttpStatusCode.OK) { Content = content }; - - return (TOutput)Convert.ChangeType(response, typeof(TOutput)); -#elif NETSTANDARD2_0 - var content = new ContentResult() - { - Content = JsonConvert.SerializeObject(result), - ContentType = "application/json", - StatusCode = (int)HttpStatusCode.OK - }; - - return (TOutput)(IActionResult)content; -#endif - } - } -} \ No newline at end of file diff --git a/samples/Aliencube.AzureFunctions.FunctionAppCommon/Functions/SampleTimerFunction.cs b/samples/Aliencube.AzureFunctions.FunctionAppCommon/Functions/SampleTimerFunction.cs deleted file mode 100644 index 28a07d6..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionAppCommon/Functions/SampleTimerFunction.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; -using System.Threading.Tasks; - -using Aliencube.AzureFunctions.Extensions.DependencyInjection.Abstractions; -using Aliencube.AzureFunctions.FunctionAppCommon.Functions.FunctionOptions; - -using Microsoft.Extensions.Logging; - -namespace Aliencube.AzureFunctions.FunctionAppCommon.Functions -{ - public class SampleTimerFunction : FunctionBase, ISampleTimerFunction - { - public override async Task InvokeAsync(TInput input, FunctionOptionsBase options = null) - { - var collector = (options as SampleTimerFunctionOptions).Collector; - - var now = DateTimeOffset.UtcNow; - - this.Log.LogInformation($"C# Timer trigger function executed at: {now}"); - - await collector.AddAsync(now.ToString()).ConfigureAwait(false); - - return (TOutput)(object)true; - } - } -} \ No newline at end of file diff --git a/samples/Aliencube.AzureFunctions.FunctionAppCommon/Models/NumericEnum.cs b/samples/Aliencube.AzureFunctions.FunctionAppCommon/Models/NumericEnum.cs deleted file mode 100644 index c695c63..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionAppCommon/Models/NumericEnum.cs +++ /dev/null @@ -1,23 +0,0 @@ -namespace Aliencube.AzureFunctions.FunctionAppCommon.Models -{ - /// - /// This specifies an enum that will be serialized as a number. - /// - public enum NumericEnum : short - { - /// - /// Identifies 1. - /// - FirstValue = 1, - - /// - /// Identifies 2. - /// - SecondValue = 2, - - /// - /// Identifies 3. - /// - ThirdValue = 3 - } -} diff --git a/samples/Aliencube.AzureFunctions.FunctionAppCommon/Models/SampleGenericResponseModel.cs b/samples/Aliencube.AzureFunctions.FunctionAppCommon/Models/SampleGenericResponseModel.cs deleted file mode 100644 index e52b75d..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionAppCommon/Models/SampleGenericResponseModel.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System.Collections.Generic; - -namespace Aliencube.AzureFunctions.FunctionAppCommon.Models -{ - /// - /// This represents the generic model entity. - /// - /// Type of item. - public class SampleGenericResponseModel - { - /// - /// Gets or sets the page. - /// - public int Page { get; set; } - - /// - /// Gets or sets the list of items. - /// - public List Items { get; set; } - - /// - /// Gets or sets the collection of items. - /// - public Dictionary Collection { get; set; } - - /// - /// Gets or sets the item. - /// - public T Item { get; set; } - } -} \ No newline at end of file diff --git a/samples/Aliencube.AzureFunctions.FunctionAppCommon/Models/SampleItemModel.cs b/samples/Aliencube.AzureFunctions.FunctionAppCommon/Models/SampleItemModel.cs deleted file mode 100644 index 1597e7f..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionAppCommon/Models/SampleItemModel.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Newtonsoft.Json; - -namespace Aliencube.AzureFunctions.FunctionAppCommon.Models -{ - /// - /// This represents the item model of a collection. - /// - public class SampleItemModel - { - /// - /// Gets or sets the first name. - /// - [JsonProperty("firstName")] - public string FirstName { get; set; } - - /// - /// Gets or sets the last name. - /// - [JsonProperty("lastName")] - public string LastName { get; set; } - } -} \ No newline at end of file diff --git a/samples/Aliencube.AzureFunctions.FunctionAppCommon/Models/SampleRequestModel.cs b/samples/Aliencube.AzureFunctions.FunctionAppCommon/Models/SampleRequestModel.cs deleted file mode 100644 index cd6798a..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionAppCommon/Models/SampleRequestModel.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Aliencube.AzureFunctions.FunctionAppCommon.Models -{ - /// - /// This represents the model entity for sample request. - /// - public class SampleRequestModel - { - /// - /// Gets or sets the Id. - /// - public string Id { get; set; } - } -} \ No newline at end of file diff --git a/samples/Aliencube.AzureFunctions.FunctionAppCommon/Models/SampleResponseModel.cs b/samples/Aliencube.AzureFunctions.FunctionAppCommon/Models/SampleResponseModel.cs deleted file mode 100644 index b8da1f3..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionAppCommon/Models/SampleResponseModel.cs +++ /dev/null @@ -1,74 +0,0 @@ -using System; -using System.Collections.Generic; - -using Aliencube.AzureFunctions.Extensions.OpenApi.Attributes; -using Aliencube.AzureFunctions.Extensions.OpenApi.Enums; - -using Newtonsoft.Json; - -namespace Aliencube.AzureFunctions.FunctionAppCommon.Models -{ - /// - /// This represents the model entity for sample response. - /// - public class SampleResponseModel - { - /// - /// Gets or sets the Id. - /// - public Guid Id { get; set; } - - /// - /// Gets or sets the name. - /// - [OpenApiSchemaVisibility(OpenApiVisibilityType.Advanced)] - public string Name { get; set; } - - /// - /// Gets or sets the description. - /// - [JsonIgnore] - public string Description { get; set; } - - /// - /// Gets or sets the instance. - /// - [JsonProperty("subModel")] - public SubSampleResponseModel Sub { get; set; } - - /// - /// Gets or sets the dictionary object. - /// - public Dictionary Collection { get; set; } = new Dictionary(); - - /// - /// Gets or sets the list objects 1. - /// - public List Items1 { get; set; } = new List(); - - /// - /// Gets or sets the list of objects 2. - /// - public int[] Items2 { get; set; } = new List().ToArray(); - - /// - /// Gets or sets the date time value. - /// - public DateTime DateTimeValue { get; set; } - - /// - /// Gets or sets the date time offset value. - /// - public DateTimeOffset DateTimeOffsetValue { get; set; } - - /// - /// Gets or sets an enum value. - /// - public StringEnum EnumValueAsString { get; set; } - - /// - /// Gets or sets an enum value. - /// - public NumericEnum EnumValueAsNumber { get; set; } - } -} \ No newline at end of file diff --git a/samples/Aliencube.AzureFunctions.FunctionAppCommon/Models/StringEnum.cs b/samples/Aliencube.AzureFunctions.FunctionAppCommon/Models/StringEnum.cs deleted file mode 100644 index 3b285aa..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionAppCommon/Models/StringEnum.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; - -namespace Aliencube.AzureFunctions.FunctionAppCommon.Models -{ - /// - /// This specifies an enum that will be serialized as a string. - /// - [JsonConverter(typeof(StringEnumConverter))] - public enum StringEnum - { - /// - /// Identifies "off". - /// - Off = 0, - - /// - /// Identifies "on". - /// - On = 1 - } -} \ No newline at end of file diff --git a/samples/Aliencube.AzureFunctions.FunctionAppCommon/Models/SubSampleResponseModel.cs b/samples/Aliencube.AzureFunctions.FunctionAppCommon/Models/SubSampleResponseModel.cs deleted file mode 100644 index 954502f..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionAppCommon/Models/SubSampleResponseModel.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace Aliencube.AzureFunctions.FunctionAppCommon.Models -{ - /// - /// This represents the sub model entity for sample response - /// - public class SubSampleResponseModel - { - /// - /// Gets or sets the key. - /// - public string Key { get; set; } - - /// - /// Gets or sets the value. - /// - public int Value { get; set; } - } -} \ No newline at end of file diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV1/.gitignore b/samples/Aliencube.AzureFunctions.FunctionAppV1/.gitignore deleted file mode 100644 index fea9bfe..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionAppV1/.gitignore +++ /dev/null @@ -1,264 +0,0 @@ -## Ignore Visual Studio temporary files, build results, and -## files generated by popular Visual Studio add-ons. - -# Azure Functions localsettings file -#local.settings.json - -# User-specific files -*.suo -*.user -*.userosscache -*.sln.docstates - -# User-specific files (MonoDevelop/Xamarin Studio) -*.userprefs - -# Build results -[Dd]ebug/ -[Dd]ebugPublic/ -[Rr]elease/ -[Rr]eleases/ -x64/ -x86/ -bld/ -[Bb]in/ -[Oo]bj/ -[Ll]og/ - -# Visual Studio 2015 cache/options directory -.vs/ -# Uncomment if you have tasks that create the project's static files in wwwroot -#wwwroot/ - -# MSTest test Results -[Tt]est[Rr]esult*/ -[Bb]uild[Ll]og.* - -# NUNIT -*.VisualState.xml -TestResult.xml - -# Build Results of an ATL Project -[Dd]ebugPS/ -[Rr]eleasePS/ -dlldata.c - -# DNX -project.lock.json -project.fragment.lock.json -artifacts/ - -*_i.c -*_p.c -*_i.h -*.ilk -*.meta -*.obj -*.pch -*.pdb -*.pgc -*.pgd -*.rsp -*.sbr -*.tlb -*.tli -*.tlh -*.tmp -*.tmp_proj -*.log -*.vspscc -*.vssscc -.builds -*.pidb -*.svclog -*.scc - -# Chutzpah Test files -_Chutzpah* - -# Visual C++ cache files -ipch/ -*.aps -*.ncb -*.opendb -*.opensdf -*.sdf -*.cachefile -*.VC.db -*.VC.VC.opendb - -# Visual Studio profiler -*.psess -*.vsp -*.vspx -*.sap - -# TFS 2012 Local Workspace -$tf/ - -# Guidance Automation Toolkit -*.gpState - -# ReSharper is a .NET coding add-in -_ReSharper*/ -*.[Rr]e[Ss]harper -*.DotSettings.user - -# JustCode is a .NET coding add-in -.JustCode - -# TeamCity is a build add-in -_TeamCity* - -# DotCover is a Code Coverage Tool -*.dotCover - -# NCrunch -_NCrunch_* -.*crunch*.local.xml -nCrunchTemp_* - -# MightyMoose -*.mm.* -AutoTest.Net/ - -# Web workbench (sass) -.sass-cache/ - -# Installshield output folder -[Ee]xpress/ - -# DocProject is a documentation generator add-in -DocProject/buildhelp/ -DocProject/Help/*.HxT -DocProject/Help/*.HxC -DocProject/Help/*.hhc -DocProject/Help/*.hhk -DocProject/Help/*.hhp -DocProject/Help/Html2 -DocProject/Help/html - -# Click-Once directory -publish/ - -# Publish Web Output -*.[Pp]ublish.xml -*.azurePubxml -# TODO: Comment the next line if you want to checkin your web deploy settings -# but database connection strings (with potential passwords) will be unencrypted -#*.pubxml -*.publishproj - -# Microsoft Azure Web App publish settings. Comment the next line if you want to -# checkin your Azure Web App publish settings, but sensitive information contained -# in these scripts will be unencrypted -PublishScripts/ - -# NuGet Packages -*.nupkg -# The packages folder can be ignored because of Package Restore -**/packages/* -# except build/, which is used as an MSBuild target. -!**/packages/build/ -# Uncomment if necessary however generally it will be regenerated when needed -#!**/packages/repositories.config -# NuGet v3's project.json files produces more ignoreable files -*.nuget.props -*.nuget.targets - -# Microsoft Azure Build Output -csx/ -*.build.csdef - -# Microsoft Azure Emulator -ecf/ -rcf/ - -# Windows Store app package directories and files -AppPackages/ -BundleArtifacts/ -Package.StoreAssociation.xml -_pkginfo.txt - -# Visual Studio cache files -# files ending in .cache can be ignored -*.[Cc]ache -# but keep track of directories ending in .cache -!*.[Cc]ache/ - -# Others -ClientBin/ -~$* -*~ -*.dbmdl -*.dbproj.schemaview -*.jfm -*.pfx -*.publishsettings -node_modules/ -orleans.codegen.cs - -# Since there are multiple workflows, uncomment next line to ignore bower_components -# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) -#bower_components/ - -# RIA/Silverlight projects -Generated_Code/ - -# Backup & report files from converting an old project file -# to a newer Visual Studio version. Backup files are not needed, -# because we have git ;-) -_UpgradeReport_Files/ -Backup*/ -UpgradeLog*.XML -UpgradeLog*.htm - -# SQL Server files -*.mdf -*.ldf - -# Business Intelligence projects -*.rdl.data -*.bim.layout -*.bim_*.settings - -# Microsoft Fakes -FakesAssemblies/ - -# GhostDoc plugin setting file -*.GhostDoc.xml - -# Node.js Tools for Visual Studio -.ntvs_analysis.dat - -# Visual Studio 6 build log -*.plg - -# Visual Studio 6 workspace options file -*.opt - -# Visual Studio LightSwitch build output -**/*.HTMLClient/GeneratedArtifacts -**/*.DesktopClient/GeneratedArtifacts -**/*.DesktopClient/ModelManifest.xml -**/*.Server/GeneratedArtifacts -**/*.Server/ModelManifest.xml -_Pvt_Extensions - -# Paket dependency manager -.paket/paket.exe -paket-files/ - -# FAKE - F# Make -.fake/ - -# JetBrains Rider -.idea/ -*.sln.iml - -# CodeRush -.cr/ - -# Python Tools for Visual Studio (PTVS) -__pycache__/ -*.pyc \ No newline at end of file diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV1/Aliencube.AzureFunctions.FunctionAppV1.csproj b/samples/Aliencube.AzureFunctions.FunctionAppV1/Aliencube.AzureFunctions.FunctionAppV1.csproj deleted file mode 100644 index 0c3ec82..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionAppV1/Aliencube.AzureFunctions.FunctionAppV1.csproj +++ /dev/null @@ -1,30 +0,0 @@ - - - - net461 - v1 - - - - - - - - - - - - - - - - - PreserveNewest - - - PreserveNewest - Never - - - - diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV1/OpenApiHttpTrigger.cs b/samples/Aliencube.AzureFunctions.FunctionAppV1/OpenApiHttpTrigger.cs deleted file mode 100644 index fbd9866..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionAppV1/OpenApiHttpTrigger.cs +++ /dev/null @@ -1,167 +0,0 @@ -using System.Net.Http; -using System.Reflection; -using System.Threading.Tasks; - -using Aliencube.AzureFunctions.Extensions.DependencyInjection; -using Aliencube.AzureFunctions.Extensions.DependencyInjection.Abstractions; -using Aliencube.AzureFunctions.Extensions.OpenApi.Attributes; -using Aliencube.AzureFunctions.FunctionAppCommon.Functions; -using Aliencube.AzureFunctions.FunctionAppCommon.Functions.FunctionOptions; - -using Microsoft.Azure.WebJobs; -using Microsoft.Azure.WebJobs.Extensions.Http; -using Microsoft.Extensions.Logging; - -namespace Aliencube.AzureFunctions.FunctionAppV1 -{ - /// - /// This represents the HTTP trigger for Open API. - /// - public static class OpenApiHttpTrigger - { - /// - /// Gets the instance as an IoC container. - /// - public static IFunctionFactory Factory { get; set; } = new FunctionFactory(); - - /// - /// Invokes the HTTP trigger endpoint to get Open API document in JSON. - /// - /// instance. - /// instance. - /// Open API document in JSON. - [FunctionName(nameof(RenderSwaggerJson))] - [OpenApiIgnore] - public static async Task RenderSwaggerJson( - [HttpTrigger(AuthorizationLevel.Function, "get", Route = "swagger.json")] HttpRequestMessage req, - ILogger log) - { - var options = new RenderOpeApiDocumentFunctionOptions("v2", "json", Assembly.GetExecutingAssembly()); - var result = await Factory.Create(log) - .InvokeAsync(req, options) - .ConfigureAwait(false); - - return result; - } - - /// - /// Invokes the HTTP trigger endpoint to get Open API document in YAML. - /// - /// instance. - /// instance. - /// Open API document in YAML. - [FunctionName(nameof(RenderSwaggerYaml))] - [OpenApiIgnore] - public static async Task RenderSwaggerYaml( - [HttpTrigger(AuthorizationLevel.Function, "get", Route = "swagger.yaml")] HttpRequestMessage req, - ILogger log) - { - var options = new RenderOpeApiDocumentFunctionOptions("v2", "yaml", Assembly.GetExecutingAssembly()); - var result = await Factory.Create(log) - .InvokeAsync(req, options) - .ConfigureAwait(false); - - return result; - } - - /// - /// Invokes the HTTP trigger endpoint to get Open API document V2 in JSON. - /// - /// instance. - /// instance. - /// Open API document in JSON. - [FunctionName(nameof(RenderOpenApiV2Json))] - [OpenApiIgnore] - public static async Task RenderOpenApiV2Json( - [HttpTrigger(AuthorizationLevel.Function, "get", Route = "openapi/v2.json")] HttpRequestMessage req, - ILogger log) - { - var options = new RenderOpeApiDocumentFunctionOptions("v2", "json", Assembly.GetExecutingAssembly()); - var result = await Factory.Create(log) - .InvokeAsync(req, options) - .ConfigureAwait(false); - - return result; - } - - /// - /// Invokes the HTTP trigger endpoint to get Open API document V2 in YAML. - /// - /// instance. - /// instance. - /// Open API document in YAML. - [FunctionName(nameof(RenderOpenApiV2Yaml))] - [OpenApiIgnore] - public static async Task RenderOpenApiV2Yaml( - [HttpTrigger(AuthorizationLevel.Function, "get", Route = "openapi/v2.yaml")] HttpRequestMessage req, - ILogger log) - { - var options = new RenderOpeApiDocumentFunctionOptions("v2", "yaml", Assembly.GetExecutingAssembly()); - var result = await Factory.Create(log) - .InvokeAsync(req, options) - .ConfigureAwait(false); - - return result; - } - - /// - /// Invokes the HTTP trigger endpoint to get Open API document V3 in JSON. - /// - /// instance. - /// instance. - /// Open API document in JSON. - [FunctionName(nameof(RenderOpenApiV3Json))] - [OpenApiIgnore] - public static async Task RenderOpenApiV3Json( - [HttpTrigger(AuthorizationLevel.Function, "get", Route = "openapi/v3.json")] HttpRequestMessage req, - ILogger log) - { - var options = new RenderOpeApiDocumentFunctionOptions("v3", "json", Assembly.GetExecutingAssembly()); - var result = await Factory.Create(log) - .InvokeAsync(req, options) - .ConfigureAwait(false); - - return result; - } - - /// - /// Invokes the HTTP trigger endpoint to get Open API document V3 in YAML. - /// - /// instance. - /// instance. - /// Open API document in YAML. - [FunctionName(nameof(RenderOpenApiV3Yaml))] - [OpenApiIgnore] - public static async Task RenderOpenApiV3Yaml( - [HttpTrigger(AuthorizationLevel.Function, "get", Route = "openapi/v3.yaml")] HttpRequestMessage req, - ILogger log) - { - var options = new RenderOpeApiDocumentFunctionOptions("v3", "yaml", Assembly.GetExecutingAssembly()); - var result = await Factory.Create(log) - .InvokeAsync(req, options) - .ConfigureAwait(false); - - return result; - } - - /// - /// Invokes the HTTP trigger endpoint to render Swagger UI in HTML. - /// - /// instance. - /// instance. - /// Swagger UI in HTML. - [FunctionName(nameof(RenderSwaggerUI))] - [OpenApiIgnore] - public static async Task RenderSwaggerUI( - [HttpTrigger(AuthorizationLevel.Function, "get", Route = "swagger/ui")] HttpRequestMessage req, - ILogger log) - { - var options = new RenderSwaggerUIFunctionOptions(); - var result = await Factory.Create(log) - .InvokeAsync(req, options) - .ConfigureAwait(false); - - return result; - } - } -} \ No newline at end of file diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV1/SampleHttpTrigger.cs b/samples/Aliencube.AzureFunctions.FunctionAppV1/SampleHttpTrigger.cs deleted file mode 100644 index 5a799f9..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionAppV1/SampleHttpTrigger.cs +++ /dev/null @@ -1,74 +0,0 @@ -using System.Net; -using System.Net.Http; -using System.Threading.Tasks; - -using Aliencube.AzureFunctions.Extensions.DependencyInjection; -using Aliencube.AzureFunctions.Extensions.DependencyInjection.Abstractions; -using Aliencube.AzureFunctions.Extensions.OpenApi.Attributes; -using Aliencube.AzureFunctions.Extensions.OpenApi.Enums; -using Aliencube.AzureFunctions.FunctionAppCommon.Functions; -using Aliencube.AzureFunctions.FunctionAppCommon.Models; - -using Microsoft.Azure.WebJobs; -using Microsoft.Azure.WebJobs.Extensions.Http; -using Microsoft.Extensions.Logging; -using Microsoft.OpenApi.Models; - -namespace Aliencube.AzureFunctions.FunctionAppV1 -{ - /// - /// This represents the HTTP trigger. - /// - public static class SampleHttpTrigger - { - /// - /// Gets the instance as an IoC container. - /// - public static IFunctionFactory Factory = new FunctionFactory(); - - /// - /// Invokes the HTTP trigger endpoint to get sample. - /// - /// instance. - /// instance. - /// instance. - [FunctionName(nameof(GetSample))] - [OpenApiOperation(operationId: "list", tags: new[] { "sample" }, Summary = "Gets the list of samples", Description = "This gets the list of samples.", Visibility = OpenApiVisibilityType.Important)] - [OpenApiParameter(name: "id", In = ParameterLocation.Path, Required = true, Type = typeof(int), Summary = "The ID parameter", Visibility = OpenApiVisibilityType.Advanced)] - [OpenApiParameter(name: "category", In = ParameterLocation.Path, Required = true, Type = typeof(string), Summary = "The category parameter", Visibility = OpenApiVisibilityType.Advanced)] - [OpenApiParameter(name: "name", In = ParameterLocation.Query, Required = true, Type = typeof(string), Summary = "The name query key", Visibility = OpenApiVisibilityType.Advanced)] - [OpenApiParameter(name: "limit", In = ParameterLocation.Query, Required = false, Type = typeof(int), Description = "The number of samples to return")] - [OpenApiResponseBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(SampleResponseModel), Summary = "Sample response")] - public static async Task GetSample( - [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "samples/{id:int}/categories/{category:regex(^[a-z]{{3,}}$)}")] HttpRequestMessage req, - ILogger log) - { - var result = await Factory.Create(log) - .InvokeAsync(req) - .ConfigureAwait(false); - - return result; - } - - /// - /// Invokes the HTTP trigger endpoint to create sample. - /// - /// instance. - /// instance. - /// instance. - [FunctionName(nameof(PostSample))] - [OpenApiOperation(operationId: "add", tags: new[] { "sample" })] - [OpenApiRequestBody(contentType: "application/json", bodyType: typeof(SampleRequestModel))] - [OpenApiResponseBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(SampleResponseModel))] - public static async Task PostSample( - [HttpTrigger(AuthorizationLevel.Function, "post", Route = "samples")] HttpRequestMessage req, - ILogger log) - { - var result = await Factory.Create(log) - .InvokeAsync(req) - .ConfigureAwait(false); - - return result; - } - } -} \ No newline at end of file diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV1/SampleTimerTrigger.cs b/samples/Aliencube.AzureFunctions.FunctionAppV1/SampleTimerTrigger.cs deleted file mode 100644 index 88c4ad8..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionAppV1/SampleTimerTrigger.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System.Threading.Tasks; - -using Aliencube.AzureFunctions.Extensions.DependencyInjection; -using Aliencube.AzureFunctions.Extensions.DependencyInjection.Abstractions; -using Aliencube.AzureFunctions.FunctionAppCommon.Functions; -using Aliencube.AzureFunctions.FunctionAppCommon.Functions.FunctionOptions; - -using Microsoft.Azure.WebJobs; -using Microsoft.Extensions.Logging; - -namespace Aliencube.AzureFunctions.FunctionAppV1 -{ - /// - /// This represents the timer trigger. - /// - public static class SampleTimerTrigger - { - /// - /// Gets the instance as an IoC container. - /// - public static IFunctionFactory Factory = new FunctionFactory(typeof(StartUp)); - - /// - /// Invokes the timer trigger. - /// - /// instance. - /// instance. - /// instance. - /// instance. - [FunctionName(nameof(Run))] - public static async Task Run( - [TimerTrigger("0/5 * * * * *")] TimerInfo myTimer, - [Queue("output")] IAsyncCollector collector, - ILogger log) - { - var options = new SampleTimerFunctionOptions() { Collector = collector }; - - var result = await Factory.Create(log) - .InvokeAsync(myTimer, options) - .ConfigureAwait(false); - - Factory.ResultInvoked = result; - } - } -} \ No newline at end of file diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV1/StartUp.cs b/samples/Aliencube.AzureFunctions.FunctionAppV1/StartUp.cs deleted file mode 100644 index 72cb101..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionAppV1/StartUp.cs +++ /dev/null @@ -1,36 +0,0 @@ -using Aliencube.AzureFunctions.Extensions.DependencyInjection.Abstractions; -using Aliencube.AzureFunctions.Extensions.OpenApi; -using Aliencube.AzureFunctions.Extensions.OpenApi.Abstractions; -using Aliencube.AzureFunctions.Extensions.OpenApi.Configurations; -using Aliencube.AzureFunctions.FunctionAppCommon.Configurations; -using Aliencube.AzureFunctions.FunctionAppCommon.Dependencies; -using Aliencube.AzureFunctions.FunctionAppCommon.Functions; - -using Microsoft.Extensions.DependencyInjection; - -namespace Aliencube.AzureFunctions.FunctionAppV1 -{ - /// - /// This represents the module entity to register dependencies. - /// - public class StartUp : Module - { - /// - public override void Load(IServiceCollection services) - { - services.AddSingleton(); - services.AddSingleton(); - - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - - services.AddTransient(); - } - } -} \ No newline at end of file diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV1/local.settings.json b/samples/Aliencube.AzureFunctions.FunctionAppV1/local.settings.json deleted file mode 100644 index 8265187..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionAppV1/local.settings.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "IsEncrypted": false, - "Values": { - "AzureWebJobsStorage": "UseDevelopmentStorage=true", - "AzureWebJobsDashboard": "UseDevelopmentStorage=true", - - "OpenApi__Info__Version": "1.0.0", - "OpenApi__Info__Title": "Open API Sample on Azure Functions", - "OpenApi__Info__Description": "A sample API that runs on Azure Functions 1.x using Open API specification.", - "OpenApi__Info__TermsOfService": "https://github.com/aliencube/AzureFunctions.Extensions", - "OpenApi__Info__Contact__Name": "Aliencube Community", - "OpenApi__Info__Contact__Email": "no-reply@aliencube.org", - "OpenApi__Info__Contact__Url": "https://github.com/aliencube/AzureFunctions.Extensions/issues", - "OpenApi__Info__License__Name": "MIT", - "OpenApi__Info__License__Url": "http://opensource.org/licenses/MIT", - - "OpenApi__ApiKey": "" - } -} \ No newline at end of file diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV1IoC/Aliencube.AzureFunctions.FunctionAppV1IoC.csproj b/samples/Aliencube.AzureFunctions.FunctionAppV1IoC/Aliencube.AzureFunctions.FunctionAppV1IoC.csproj index c8dc2e4..35ff5db 100644 --- a/samples/Aliencube.AzureFunctions.FunctionAppV1IoC/Aliencube.AzureFunctions.FunctionAppV1IoC.csproj +++ b/samples/Aliencube.AzureFunctions.FunctionAppV1IoC/Aliencube.AzureFunctions.FunctionAppV1IoC.csproj @@ -6,7 +6,7 @@ - + diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV1IoC/DummyHttpTrigger.cs b/samples/Aliencube.AzureFunctions.FunctionAppV1IoC/DummyHttpTrigger.cs new file mode 100644 index 0000000..2b32a2f --- /dev/null +++ b/samples/Aliencube.AzureFunctions.FunctionAppV1IoC/DummyHttpTrigger.cs @@ -0,0 +1,64 @@ +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Net; +using System.Net.Http; +using System.Threading.Tasks; + +using Aliencube.AzureFunctions.Extensions.DependencyInjection; +using Aliencube.AzureFunctions.Extensions.DependencyInjection.Abstractions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums; +using Aliencube.AzureFunctions.FunctionApp.Functions; +using Aliencube.AzureFunctions.FunctionApp.Models; +using Aliencube.AzureFunctions.FunctionAppV1IoC; + +using Microsoft.Azure.WebJobs; +using Microsoft.Azure.WebJobs.Extensions.Http; +using Microsoft.Extensions.Logging; +using Microsoft.OpenApi.Models; + +namespace Aliencube.AzureFunctions.FunctionAppV1Static +{ + public static class DummyHttpTrigger + { + /// + /// Gets the instance as an IoC container. + /// + [SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "")] + public static IFunctionFactory Factory = new FunctionFactory(); + + [FunctionName(nameof(DummyHttpTrigger.GetDummies))] + [OpenApiOperation(operationId: "getDummies", tags: new[] { "dummy" }, Summary = "Gets the list of dummies", Description = "This gets the list of dummies.", Visibility = OpenApiVisibilityType.Important)] + [OpenApiParameter(name: "name", In = ParameterLocation.Query, Required = true, Type = typeof(string), Summary = "Dummy name", Description = "Dummy name", Visibility = OpenApiVisibilityType.Important)] + [OpenApiParameter(name: "switch", In = ParameterLocation.Path, Required = true, Type = typeof(StringEnum), Summary = "Dummy switch", Description = "Dummy switch", Visibility = OpenApiVisibilityType.Important)] + [OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(List), Summary = "List of the dummy responses", Description = "This returns the list of dummy responses")] + [OpenApiResponseWithoutBody(statusCode: HttpStatusCode.NotFound, Summary = "Name not found", Description = "Name parameter is not found")] + [OpenApiResponseWithoutBody(statusCode: HttpStatusCode.BadRequest, Summary = "Invalid switch", Description = "Switch parameter is not valid")] + public static async Task GetDummies( + [HttpTrigger(AuthorizationLevel.Function, "GET", Route = "dummies")] HttpRequestMessage req, + ILogger log) + { + var result = await Factory.Create(log) + .InvokeAsync(req) + .ConfigureAwait(false); + + return result; + } + + [FunctionName(nameof(DummyHttpTrigger.AddDummy))] + [OpenApiOperation(operationId: "addDummy", tags: new[] { "dummy" }, Summary = "Adds a dummy", Description = "This adds a dummy.", Visibility = OpenApiVisibilityType.Advanced)] + [OpenApiRequestBody(contentType: "application/json", bodyType: typeof(DummyRequestModel), Required = true, Description = "Dummy request model")] + [OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(DummyResponseModel), Summary = "Dummy response", Description = "This returns the dummy response")] + [OpenApiResponseWithoutBody(statusCode: HttpStatusCode.BadRequest, Summary = "Invalid request payload", Description = "Request payload is not valid")] + public static async Task AddDummy( + [HttpTrigger(AuthorizationLevel.Function, "POST", Route = "dummies")] HttpRequestMessage req, + ILogger log) + { + var result = await Factory.Create(log) + .InvokeAsync(req) + .ConfigureAwait(false); + + return result; + } + } +} diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV1IoC/PetStoreHttpTrigger.cs b/samples/Aliencube.AzureFunctions.FunctionAppV1IoC/PetStoreHttpTrigger.cs index 9138e12..b5c8723 100644 --- a/samples/Aliencube.AzureFunctions.FunctionAppV1IoC/PetStoreHttpTrigger.cs +++ b/samples/Aliencube.AzureFunctions.FunctionAppV1IoC/PetStoreHttpTrigger.cs @@ -6,8 +6,8 @@ using Aliencube.AzureFunctions.Extensions.DependencyInjection; using Aliencube.AzureFunctions.Extensions.DependencyInjection.Abstractions; -using Aliencube.AzureFunctions.Extensions.OpenApi.Attributes; -using Aliencube.AzureFunctions.Extensions.OpenApi.Enums; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums; using Aliencube.AzureFunctions.FunctionApp.Models; using Microsoft.Azure.WebJobs; diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV1IoC/SampleHttpTrigger.cs b/samples/Aliencube.AzureFunctions.FunctionAppV1IoC/SampleHttpTrigger.cs deleted file mode 100644 index 8300e74..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionAppV1IoC/SampleHttpTrigger.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Net; -using System.Net.Http; -using System.Threading.Tasks; - -using Aliencube.AzureFunctions.Extensions.DependencyInjection; -using Aliencube.AzureFunctions.Extensions.DependencyInjection.Abstractions; -using Aliencube.AzureFunctions.Extensions.OpenApi.Attributes; -using Aliencube.AzureFunctions.Extensions.OpenApi.Enums; -using Aliencube.AzureFunctions.FunctionApp.Functions; -using Aliencube.AzureFunctions.FunctionApp.Models; - -using Microsoft.Azure.WebJobs; -using Microsoft.Azure.WebJobs.Extensions.Http; -using Microsoft.Extensions.Logging; - -namespace Aliencube.AzureFunctions.FunctionAppV1IoC -{ - public static class SampleHttpTrigger - { - /// - /// Gets the instance as an IoC container. - /// - [SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "")] - public static IFunctionFactory Factory = new FunctionFactory(); - - [FunctionName(nameof(SampleHttpTrigger.GetSamples))] - [OpenApiOperation(operationId: "list", tags: new[] { "sample" }, Summary = "Gets the list of samples", Description = "This gets the list of samples.", Visibility = OpenApiVisibilityType.Important)] - [OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(List), Summary = "List of the sample responses")] - public static async Task GetSamples( - [HttpTrigger(AuthorizationLevel.Function, "get", Route = "samples")] HttpRequestMessage req, - ILogger log) - { - var result = await Factory.Create(log) - .InvokeAsync(req) - .ConfigureAwait(false); - - return result; - } - } -} diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV1IoC/StartUp.cs b/samples/Aliencube.AzureFunctions.FunctionAppV1IoC/StartUp.cs index 99961d0..838380a 100644 --- a/samples/Aliencube.AzureFunctions.FunctionAppV1IoC/StartUp.cs +++ b/samples/Aliencube.AzureFunctions.FunctionAppV1IoC/StartUp.cs @@ -1,4 +1,4 @@ -using Aliencube.AzureFunctions.Extensions.DependencyInjection.Abstractions; +using Aliencube.AzureFunctions.Extensions.DependencyInjection.Abstractions; using Aliencube.AzureFunctions.FunctionApp.Functions; using Aliencube.AzureFunctions.FunctionApp.Services; @@ -14,9 +14,10 @@ public class StartUp : Module /// public override void Load(IServiceCollection services) { - services.AddTransient(); + services.AddTransient(); - services.AddTransient(); + services.AddTransient(); + services.AddTransient(); } } -} \ No newline at end of file +} diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV1Static/Aliencube.AzureFunctions.FunctionAppV1Static.csproj b/samples/Aliencube.AzureFunctions.FunctionAppV1Static/Aliencube.AzureFunctions.FunctionAppV1Static.csproj index 17b7ee5..57b109f 100644 --- a/samples/Aliencube.AzureFunctions.FunctionAppV1Static/Aliencube.AzureFunctions.FunctionAppV1Static.csproj +++ b/samples/Aliencube.AzureFunctions.FunctionAppV1Static/Aliencube.AzureFunctions.FunctionAppV1Static.csproj @@ -6,7 +6,7 @@ - + diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV1Static/DummyHttpTrigger.cs b/samples/Aliencube.AzureFunctions.FunctionAppV1Static/DummyHttpTrigger.cs new file mode 100644 index 0000000..b952031 --- /dev/null +++ b/samples/Aliencube.AzureFunctions.FunctionAppV1Static/DummyHttpTrigger.cs @@ -0,0 +1,54 @@ +using System.Collections.Generic; +using System.Net; +using System.Net.Http; +using System.Threading.Tasks; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums; +using Aliencube.AzureFunctions.FunctionApp.Models; + +using Microsoft.Azure.WebJobs; +using Microsoft.Azure.WebJobs.Extensions.Http; +using Microsoft.Extensions.Logging; +using Microsoft.OpenApi.Models; + +namespace Aliencube.AzureFunctions.FunctionAppV1Static +{ + public static class DummyHttpTrigger + { + [FunctionName(nameof(DummyHttpTrigger.GetDummies))] + [OpenApiOperation(operationId: "getDummies", tags: new[] { "dummy" }, Summary = "Gets the list of dummies", Description = "This gets the list of dummies.", Visibility = OpenApiVisibilityType.Important)] + [OpenApiParameter(name: "name", In = ParameterLocation.Query, Required = true, Type = typeof(string), Summary = "Dummy name", Description = "Dummy name", Visibility = OpenApiVisibilityType.Important)] + [OpenApiParameter(name: "switch", In = ParameterLocation.Path, Required = true, Type = typeof(StringEnum), Summary = "Dummy switch", Description = "Dummy switch", Visibility = OpenApiVisibilityType.Important)] + [OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(List), Summary = "List of the dummy responses", Description = "This returns the list of dummy responses")] + [OpenApiResponseWithoutBody(statusCode: HttpStatusCode.NotFound, Summary = "Name not found", Description = "Name parameter is not found")] + [OpenApiResponseWithoutBody(statusCode: HttpStatusCode.BadRequest, Summary = "Invalid switch", Description = "Switch parameter is not valid")] + public static async Task GetDummies( + [HttpTrigger(AuthorizationLevel.Function, "GET", Route = "dummies")] HttpRequestMessage req, + ILogger log) + { + var content = new List() + { + new DummyResponseModel(), + }; + var result = req.CreateResponse(HttpStatusCode.OK, content); + + return await Task.FromResult(result).ConfigureAwait(false); + } + + [FunctionName(nameof(DummyHttpTrigger.AddDummy))] + [OpenApiOperation(operationId: "addDummy", tags: new[] { "dummy" }, Summary = "Adds a dummy", Description = "This adds a dummy.", Visibility = OpenApiVisibilityType.Advanced)] + [OpenApiRequestBody(contentType: "application/json", bodyType: typeof(DummyRequestModel), Required = true, Description = "Dummy request model")] + [OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(DummyResponseModel), Summary = "Dummy response", Description = "This returns the dummy response")] + [OpenApiResponseWithoutBody(statusCode: HttpStatusCode.BadRequest, Summary = "Invalid request payload", Description = "Request payload is not valid")] + public static async Task AddDummy( + [HttpTrigger(AuthorizationLevel.Function, "POST", Route = "dummies")] HttpRequestMessage req, + ILogger log) + { + var content = new DummyResponseModel(); + var result = req.CreateResponse(HttpStatusCode.OK, content); + + return await Task.FromResult(result).ConfigureAwait(false); + } + } +} diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV1Static/PetStoreHttpTrigger.cs b/samples/Aliencube.AzureFunctions.FunctionAppV1Static/PetStoreHttpTrigger.cs index cfe4b89..e656ca0 100644 --- a/samples/Aliencube.AzureFunctions.FunctionAppV1Static/PetStoreHttpTrigger.cs +++ b/samples/Aliencube.AzureFunctions.FunctionAppV1Static/PetStoreHttpTrigger.cs @@ -3,8 +3,8 @@ using System.Net.Http; using System.Threading.Tasks; -using Aliencube.AzureFunctions.Extensions.OpenApi.Attributes; -using Aliencube.AzureFunctions.Extensions.OpenApi.Enums; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums; using Aliencube.AzureFunctions.FunctionApp.Models; using Microsoft.Azure.WebJobs; diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV1Static/SampleHttpTrigger.cs b/samples/Aliencube.AzureFunctions.FunctionAppV1Static/SampleHttpTrigger.cs deleted file mode 100644 index d234683..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionAppV1Static/SampleHttpTrigger.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System.Collections.Generic; -using System.Net; -using System.Net.Http; -using System.Threading.Tasks; - -using Aliencube.AzureFunctions.Extensions.OpenApi.Attributes; -using Aliencube.AzureFunctions.Extensions.OpenApi.Enums; -using Aliencube.AzureFunctions.FunctionApp.Models; - -using Microsoft.Azure.WebJobs; -using Microsoft.Azure.WebJobs.Extensions.Http; -using Microsoft.Extensions.Logging; - -namespace Aliencube.AzureFunctions.FunctionAppV1Static -{ - public static class SampleHttpTrigger - { - [FunctionName(nameof(SampleHttpTrigger.GetSamples))] - [OpenApiOperation(operationId: "list", tags: new[] { "sample" }, Summary = "Gets the list of samples", Description = "This gets the list of samples.", Visibility = OpenApiVisibilityType.Important)] - [OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(List), Summary = "List of the sample responses")] - public static async Task GetSamples( - [HttpTrigger(AuthorizationLevel.Function, "get", Route = "samples")] HttpRequestMessage req, - ILogger log) - { - var content = new List() - { - new SampleResponseModel(), - }; - var result = req.CreateResponse(HttpStatusCode.OK, content); - - return await Task.FromResult(result).ConfigureAwait(false); - } - } -} diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV2/.gitignore b/samples/Aliencube.AzureFunctions.FunctionAppV2/.gitignore deleted file mode 100644 index fea9bfe..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionAppV2/.gitignore +++ /dev/null @@ -1,264 +0,0 @@ -## Ignore Visual Studio temporary files, build results, and -## files generated by popular Visual Studio add-ons. - -# Azure Functions localsettings file -#local.settings.json - -# User-specific files -*.suo -*.user -*.userosscache -*.sln.docstates - -# User-specific files (MonoDevelop/Xamarin Studio) -*.userprefs - -# Build results -[Dd]ebug/ -[Dd]ebugPublic/ -[Rr]elease/ -[Rr]eleases/ -x64/ -x86/ -bld/ -[Bb]in/ -[Oo]bj/ -[Ll]og/ - -# Visual Studio 2015 cache/options directory -.vs/ -# Uncomment if you have tasks that create the project's static files in wwwroot -#wwwroot/ - -# MSTest test Results -[Tt]est[Rr]esult*/ -[Bb]uild[Ll]og.* - -# NUNIT -*.VisualState.xml -TestResult.xml - -# Build Results of an ATL Project -[Dd]ebugPS/ -[Rr]eleasePS/ -dlldata.c - -# DNX -project.lock.json -project.fragment.lock.json -artifacts/ - -*_i.c -*_p.c -*_i.h -*.ilk -*.meta -*.obj -*.pch -*.pdb -*.pgc -*.pgd -*.rsp -*.sbr -*.tlb -*.tli -*.tlh -*.tmp -*.tmp_proj -*.log -*.vspscc -*.vssscc -.builds -*.pidb -*.svclog -*.scc - -# Chutzpah Test files -_Chutzpah* - -# Visual C++ cache files -ipch/ -*.aps -*.ncb -*.opendb -*.opensdf -*.sdf -*.cachefile -*.VC.db -*.VC.VC.opendb - -# Visual Studio profiler -*.psess -*.vsp -*.vspx -*.sap - -# TFS 2012 Local Workspace -$tf/ - -# Guidance Automation Toolkit -*.gpState - -# ReSharper is a .NET coding add-in -_ReSharper*/ -*.[Rr]e[Ss]harper -*.DotSettings.user - -# JustCode is a .NET coding add-in -.JustCode - -# TeamCity is a build add-in -_TeamCity* - -# DotCover is a Code Coverage Tool -*.dotCover - -# NCrunch -_NCrunch_* -.*crunch*.local.xml -nCrunchTemp_* - -# MightyMoose -*.mm.* -AutoTest.Net/ - -# Web workbench (sass) -.sass-cache/ - -# Installshield output folder -[Ee]xpress/ - -# DocProject is a documentation generator add-in -DocProject/buildhelp/ -DocProject/Help/*.HxT -DocProject/Help/*.HxC -DocProject/Help/*.hhc -DocProject/Help/*.hhk -DocProject/Help/*.hhp -DocProject/Help/Html2 -DocProject/Help/html - -# Click-Once directory -publish/ - -# Publish Web Output -*.[Pp]ublish.xml -*.azurePubxml -# TODO: Comment the next line if you want to checkin your web deploy settings -# but database connection strings (with potential passwords) will be unencrypted -#*.pubxml -*.publishproj - -# Microsoft Azure Web App publish settings. Comment the next line if you want to -# checkin your Azure Web App publish settings, but sensitive information contained -# in these scripts will be unencrypted -PublishScripts/ - -# NuGet Packages -*.nupkg -# The packages folder can be ignored because of Package Restore -**/packages/* -# except build/, which is used as an MSBuild target. -!**/packages/build/ -# Uncomment if necessary however generally it will be regenerated when needed -#!**/packages/repositories.config -# NuGet v3's project.json files produces more ignoreable files -*.nuget.props -*.nuget.targets - -# Microsoft Azure Build Output -csx/ -*.build.csdef - -# Microsoft Azure Emulator -ecf/ -rcf/ - -# Windows Store app package directories and files -AppPackages/ -BundleArtifacts/ -Package.StoreAssociation.xml -_pkginfo.txt - -# Visual Studio cache files -# files ending in .cache can be ignored -*.[Cc]ache -# but keep track of directories ending in .cache -!*.[Cc]ache/ - -# Others -ClientBin/ -~$* -*~ -*.dbmdl -*.dbproj.schemaview -*.jfm -*.pfx -*.publishsettings -node_modules/ -orleans.codegen.cs - -# Since there are multiple workflows, uncomment next line to ignore bower_components -# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) -#bower_components/ - -# RIA/Silverlight projects -Generated_Code/ - -# Backup & report files from converting an old project file -# to a newer Visual Studio version. Backup files are not needed, -# because we have git ;-) -_UpgradeReport_Files/ -Backup*/ -UpgradeLog*.XML -UpgradeLog*.htm - -# SQL Server files -*.mdf -*.ldf - -# Business Intelligence projects -*.rdl.data -*.bim.layout -*.bim_*.settings - -# Microsoft Fakes -FakesAssemblies/ - -# GhostDoc plugin setting file -*.GhostDoc.xml - -# Node.js Tools for Visual Studio -.ntvs_analysis.dat - -# Visual Studio 6 build log -*.plg - -# Visual Studio 6 workspace options file -*.opt - -# Visual Studio LightSwitch build output -**/*.HTMLClient/GeneratedArtifacts -**/*.DesktopClient/GeneratedArtifacts -**/*.DesktopClient/ModelManifest.xml -**/*.Server/GeneratedArtifacts -**/*.Server/ModelManifest.xml -_Pvt_Extensions - -# Paket dependency manager -.paket/paket.exe -paket-files/ - -# FAKE - F# Make -.fake/ - -# JetBrains Rider -.idea/ -*.sln.iml - -# CodeRush -.cr/ - -# Python Tools for Visual Studio (PTVS) -__pycache__/ -*.pyc \ No newline at end of file diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV2/Aliencube.AzureFunctions.FunctionAppV2.csproj b/samples/Aliencube.AzureFunctions.FunctionAppV2/Aliencube.AzureFunctions.FunctionAppV2.csproj deleted file mode 100644 index be872c5..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionAppV2/Aliencube.AzureFunctions.FunctionAppV2.csproj +++ /dev/null @@ -1,28 +0,0 @@ - - - - netcoreapp2.1 - v2 - - - - - - - - - - - - - - - PreserveNewest - - - PreserveNewest - Never - - - - \ No newline at end of file diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV2/OpenApiHttpTrigger.cs b/samples/Aliencube.AzureFunctions.FunctionAppV2/OpenApiHttpTrigger.cs deleted file mode 100644 index b79f091..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionAppV2/OpenApiHttpTrigger.cs +++ /dev/null @@ -1,103 +0,0 @@ -using System; -using System.Reflection; -using System.Threading.Tasks; - -using Aliencube.AzureFunctions.Extensions.DependencyInjection.Extensions; -using Aliencube.AzureFunctions.Extensions.OpenApi.Attributes; -using Aliencube.AzureFunctions.FunctionAppCommon.Functions; -using Aliencube.AzureFunctions.FunctionAppCommon.Functions.FunctionOptions; - -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Microsoft.Azure.WebJobs; -using Microsoft.Azure.WebJobs.Extensions.Http; -using Microsoft.Extensions.Logging; - -namespace Aliencube.AzureFunctions.FunctionAppV2 -{ - /// - /// This represents the HTTP trigger for Open API. - /// - public class OpenApiHttpTrigger - { - private readonly IRenderOpeApiDocumentFunction _docFunction; - private readonly IRenderSwaggerUIFunction _suiFunction; - - /// - /// Initializes a new instance of the class. - /// - /// instance. - /// instance. - public OpenApiHttpTrigger(IRenderOpeApiDocumentFunction docFunction, IRenderSwaggerUIFunction suiFunction) - { - this._docFunction = docFunction ?? throw new ArgumentNullException(nameof(docFunction)); - this._suiFunction = suiFunction ?? throw new ArgumentNullException(nameof(suiFunction)); - } - - /// - /// Invokes the HTTP trigger endpoint to get Open API document. - /// - /// instance. - /// File extension representing the document format. This MUST be either "json" or "yaml". - /// instance. - /// Open API document in a format of either JSON or YAML. - [FunctionName(nameof(RenderSwaggerDocument))] - [OpenApiIgnore] - public async Task RenderSwaggerDocument( - [HttpTrigger(AuthorizationLevel.Function, "get", Route = "swagger.{extension}")] HttpRequest req, - string extension, - ILogger log) - { - var options = new RenderOpeApiDocumentFunctionOptions("v2", extension, Assembly.GetExecutingAssembly()); - var result = await this._docFunction.AddLogger(log) - .InvokeAsync(req, options) - .ConfigureAwait(false); - - return result; - } - - /// - /// Invokes the HTTP trigger endpoint to get Open API document. - /// - /// instance. - /// Open API document spec version. This MUST be either "v2" or "v3". - /// File extension representing the document format. This MUST be either "json" or "yaml". - /// instance. - /// Open API document in a format of either JSON or YAML. - [FunctionName(nameof(RenderOpenApiDocument))] - [OpenApiIgnore] - public async Task RenderOpenApiDocument( - [HttpTrigger(AuthorizationLevel.Function, "get", Route = "openapi/{version}.{extension}")] HttpRequest req, - string version, - string extension, - ILogger log) - { - var options = new RenderOpeApiDocumentFunctionOptions(version, extension, Assembly.GetExecutingAssembly()); - var result = await this._docFunction.AddLogger(log) - .InvokeAsync(req, options) - .ConfigureAwait(false); - - return result; - } - - /// - /// Invokes the HTTP trigger endpoint to render Swagger UI in HTML. - /// - /// instance. - /// instance. - /// Swagger UI in HTML. - [FunctionName(nameof(RenderSwaggerUI))] - [OpenApiIgnore] - public async Task RenderSwaggerUI( - [HttpTrigger(AuthorizationLevel.Function, "get", Route = "swagger/ui")] HttpRequest req, - ILogger log) - { - var options = new RenderSwaggerUIFunctionOptions(); - var result = await this._suiFunction.AddLogger(log) - .InvokeAsync(req, options) - .ConfigureAwait(false); - - return result; - } - } -} \ No newline at end of file diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV2/SampleHttpTrigger.cs b/samples/Aliencube.AzureFunctions.FunctionAppV2/SampleHttpTrigger.cs deleted file mode 100644 index de6a213..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionAppV2/SampleHttpTrigger.cs +++ /dev/null @@ -1,97 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net; -using System.Threading.Tasks; - -using Aliencube.AzureFunctions.Extensions.DependencyInjection.Extensions; -using Aliencube.AzureFunctions.Extensions.OpenApi.Attributes; -using Aliencube.AzureFunctions.Extensions.OpenApi.Enums; -using Aliencube.AzureFunctions.FunctionAppCommon.Functions; -using Aliencube.AzureFunctions.FunctionAppCommon.Models; - -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Microsoft.Azure.WebJobs; -using Microsoft.Azure.WebJobs.Extensions.Http; -using Microsoft.Extensions.Logging; -using Microsoft.OpenApi.Models; - -using Newtonsoft.Json.Linq; - -namespace Aliencube.AzureFunctions.FunctionAppV2 -{ - /// - /// This represents the HTTP trigger. - /// - public class SampleHttpTrigger - { - private readonly ISampleHttpFunction _function; - - /// - /// Initializes a new instance of the class. - /// - /// instance. - public SampleHttpTrigger(ISampleHttpFunction function) - { - this._function = function ?? throw new ArgumentNullException(nameof(function)); - } - - /// - /// Invokes the HTTP trigger endpoint to get sample. - /// - /// instance. - /// instance. - /// instance. - [FunctionName(nameof(GetSample))] - [OpenApiOperation(operationId: "list", tags: new[] { "sample" }, Summary = "Gets the list of samples", Description = "This gets the list of samples.", Visibility = OpenApiVisibilityType.Important)] - [OpenApiParameter(name: "id", In = ParameterLocation.Path, Required = true, Type = typeof(int), Summary = "The ID parameter", Visibility = OpenApiVisibilityType.Advanced)] - [OpenApiParameter(name: "category", In = ParameterLocation.Path, Required = true, Type = typeof(string), Summary = "The category parameter", Visibility = OpenApiVisibilityType.Advanced)] - [OpenApiParameter(name: "name", In = ParameterLocation.Query, Required = true, Type = typeof(string), Summary = "The name query key", Visibility = OpenApiVisibilityType.Advanced)] - [OpenApiParameter(name: "limit", In = ParameterLocation.Query, Required = false, Type = typeof(int), Description = "The number of samples to return")] - [OpenApiResponseBody(statusCode: HttpStatusCode.Created, contentType: "application/json", bodyType: typeof(List), Summary = "Sample response of a List")] - [OpenApiResponseBody(statusCode: HttpStatusCode.Accepted, contentType: "application/json", bodyType: typeof(IList), Summary = "Sample response of a IList")] - [OpenApiResponseBody(statusCode: HttpStatusCode.NonAuthoritativeInformation, contentType: "application/json", bodyType: typeof(SampleResponseModel[]), Summary = "Sample response of a Array")] - [OpenApiResponseBody(statusCode: HttpStatusCode.BadRequest, contentType: "application/json", bodyType: typeof(Dictionary), Summary = "Sample response of a Dictionary")] - [OpenApiResponseBody(statusCode: HttpStatusCode.Unauthorized, contentType: "application/json", bodyType: typeof(IDictionary), Summary = "Sample response of a IDictionary")] - [OpenApiResponseBody(statusCode: HttpStatusCode.Forbidden, contentType: "application/json", bodyType: typeof(JObject), Summary = "Sample response of a JObject")] - [OpenApiResponseBody(statusCode: HttpStatusCode.NotFound, contentType: "application/json", bodyType: typeof(JToken), Summary = "Sample response of a JToken")] - [OpenApiResponseBody(statusCode: HttpStatusCode.InternalServerError, contentType: "application/json", bodyType: typeof(List), Summary = "Sample response of a List")] - [OpenApiResponseBody(statusCode: HttpStatusCode.NotImplemented, contentType: "application/json", bodyType: typeof(Dictionary), Summary = "Sample response of a Dictionary")] - [OpenApiResponseBody(statusCode: HttpStatusCode.BadGateway, contentType: "application/json", bodyType: typeof(SampleGenericResponseModel), Summary = "Sample response of a Generic")] - //[OpenApiResponseWithoutBody(statusCode: HttpStatusCode.NoContent)] - //[OpenApiResponseWithoutBody(statusCode: HttpStatusCode.RequestTimeout, Description = "Sample response with only status code", Summary = "Sample summary")] - public async Task GetSample( - [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "samples/{id:int}/categories/{category:regex(^[a-z]{{3,}}$)}")] HttpRequest req, - int id, - string category, - ILogger log) - { - var result = await this._function.AddLogger(log) - .InvokeAsync(req) - .ConfigureAwait(false); - - return result; - } - - /// - /// Invokes the HTTP trigger endpoint to create sample. - /// - /// instance. - /// instance. - /// instance. - [FunctionName(nameof(PostSample))] - [OpenApiOperation(operationId: "add", tags: new[] { "sample" })] - [OpenApiRequestBody(contentType: "application/json", bodyType: typeof(SampleRequestModel))] - [OpenApiResponseBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(SampleResponseModel), Summary = "Sample response")] - public async Task PostSample( - [HttpTrigger(AuthorizationLevel.Function, "post", Route = "samples")] HttpRequest req, - ILogger log) - { - var result = await this._function.AddLogger(log) - .InvokeAsync(req) - .ConfigureAwait(false); - - return result; - } - } -} diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV2/SampleTimerTrigger.cs b/samples/Aliencube.AzureFunctions.FunctionAppV2/SampleTimerTrigger.cs deleted file mode 100644 index abf44b0..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionAppV2/SampleTimerTrigger.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System; -using System.Threading.Tasks; - -using Aliencube.AzureFunctions.Extensions.DependencyInjection.Extensions; -using Aliencube.AzureFunctions.FunctionAppCommon.Functions; -using Aliencube.AzureFunctions.FunctionAppCommon.Functions.FunctionOptions; - -using Microsoft.Azure.WebJobs; -using Microsoft.Extensions.Logging; - -namespace Aliencube.AzureFunctions.FunctionAppV2 -{ - /// - /// This represents the timer trigger. - /// - public class SampleTimerTrigger - { - private readonly ISampleTimerFunction _function; - - /// - /// Initializes a new instance of the class. - /// - /// instance. - public SampleTimerTrigger(ISampleTimerFunction function) - { - this._function = function ?? throw new ArgumentNullException(nameof(function)); - } - - /// - /// Invokes the timer trigger. - /// - /// instance. - /// instance. - /// instance. - /// instance. - [FunctionName(nameof(Run))] - public async Task Run( - [TimerTrigger("0/5 * * * * *")] TimerInfo myTimer, - [Queue("output")] IAsyncCollector collector, - ILogger log) - { - var options = new SampleTimerFunctionOptions() { Collector = collector }; - - var result = await this._function.AddLogger(log) - .InvokeAsync(myTimer, options) - .ConfigureAwait(false); - } - } -} \ No newline at end of file diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV2/StartUp.cs b/samples/Aliencube.AzureFunctions.FunctionAppV2/StartUp.cs deleted file mode 100644 index c1f4c28..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionAppV2/StartUp.cs +++ /dev/null @@ -1,37 +0,0 @@ -using Aliencube.AzureFunctions.Extensions.OpenApi; -using Aliencube.AzureFunctions.Extensions.OpenApi.Abstractions; -using Aliencube.AzureFunctions.Extensions.OpenApi.Configurations; -using Aliencube.AzureFunctions.FunctionAppCommon.Configurations; -using Aliencube.AzureFunctions.FunctionAppCommon.Dependencies; -using Aliencube.AzureFunctions.FunctionAppCommon.Functions; - -using Microsoft.Azure.Functions.Extensions.DependencyInjection; -using Microsoft.Extensions.DependencyInjection; - -[assembly: FunctionsStartup(typeof(Aliencube.AzureFunctions.FunctionAppV2.StartUp))] -namespace Aliencube.AzureFunctions.FunctionAppV2 -{ - /// - /// This represents the entity to be invoked during the runtime startup. - /// - public class StartUp : FunctionsStartup - { - /// - public override void Configure(IFunctionsHostBuilder builder) - { - builder.Services.AddSingleton(); - builder.Services.AddSingleton(); - - builder.Services.AddTransient(); - builder.Services.AddTransient(); - builder.Services.AddTransient(); - - builder.Services.AddTransient(); - builder.Services.AddTransient(); - builder.Services.AddTransient(); - builder.Services.AddTransient(); - - builder.Services.AddTransient(); - } - } -} diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV2/local.settings.json b/samples/Aliencube.AzureFunctions.FunctionAppV2/local.settings.json deleted file mode 100644 index 9842c1e..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionAppV2/local.settings.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "IsEncrypted": false, - "Values": { - "AzureWebJobsStorage": "UseDevelopmentStorage=true", - "AzureWebJobsDashboard": "UseDevelopmentStorage=true", - - "FUNCTIONS_WORKER_RUNTIME": "dotnet", - - "OpenApi__Info__Version": "2.0.0", - "OpenApi__Info__Title": "Open API Sample on Azure Functions", - "OpenApi__Info__Description": "A sample API that runs on Azure Functions 2.x using Open API specification.", - "OpenApi__Info__TermsOfService": "https://github.com/aliencube/AzureFunctions.Extensions", - "OpenApi__Info__Contact__Name": "Aliencube Community", - "OpenApi__Info__Contact__Email": "no-reply@aliencube.org", - "OpenApi__Info__Contact__Url": "https://github.com/aliencube/AzureFunctions.Extensions/issues", - "OpenApi__Info__License__Name": "MIT", - "OpenApi__Info__License__Url": "http://opensource.org/licenses/MIT", - - "OpenApi__ApiKey": "" - } -} \ No newline at end of file diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV2IoC/Aliencube.AzureFunctions.FunctionAppV2IoC.csproj b/samples/Aliencube.AzureFunctions.FunctionAppV2IoC/Aliencube.AzureFunctions.FunctionAppV2IoC.csproj index 45431f0..6ab1db9 100644 --- a/samples/Aliencube.AzureFunctions.FunctionAppV2IoC/Aliencube.AzureFunctions.FunctionAppV2IoC.csproj +++ b/samples/Aliencube.AzureFunctions.FunctionAppV2IoC/Aliencube.AzureFunctions.FunctionAppV2IoC.csproj @@ -6,7 +6,7 @@ - + diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV2IoC/DummyHttpTrigger.cs b/samples/Aliencube.AzureFunctions.FunctionAppV2IoC/DummyHttpTrigger.cs new file mode 100644 index 0000000..bf86f86 --- /dev/null +++ b/samples/Aliencube.AzureFunctions.FunctionAppV2IoC/DummyHttpTrigger.cs @@ -0,0 +1,64 @@ +using System; +using System.Collections.Generic; +using System.Net; +using System.Threading.Tasks; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums; +using Aliencube.AzureFunctions.FunctionApp.Models; +using Aliencube.AzureFunctions.FunctionApp.Services; + +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Azure.WebJobs; +using Microsoft.Azure.WebJobs.Extensions.Http; +using Microsoft.Extensions.Logging; +using Microsoft.OpenApi.Models; + +namespace Aliencube.AzureFunctions.FunctionAppV2IoC +{ + public class DummyHttpTrigger + { + private readonly IDummyHttpService _service; + + public DummyHttpTrigger(IDummyHttpService service) + { + this._service = service ?? throw new ArgumentNullException(nameof(service)); + } + + [FunctionName(nameof(DummyHttpTrigger.GetDummies))] + [OpenApiOperation(operationId: "getDummies", tags: new[] { "dummy" }, Summary = "Gets the list of dummies", Description = "This gets the list of dummies.", Visibility = OpenApiVisibilityType.Important)] + [OpenApiParameter(name: "name", In = ParameterLocation.Query, Required = true, Type = typeof(string), Summary = "Dummy name", Description = "Dummy name", Visibility = OpenApiVisibilityType.Important)] + [OpenApiParameter(name: "switch", In = ParameterLocation.Path, Required = true, Type = typeof(StringEnum), Summary = "Dummy switch", Description = "Dummy switch", Visibility = OpenApiVisibilityType.Important)] + [OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(List), Summary = "List of the dummy responses", Description = "This returns the list of dummy responses")] + [OpenApiResponseWithoutBody(statusCode: HttpStatusCode.NotFound, Summary = "Name not found", Description = "Name parameter is not found")] + [OpenApiResponseWithoutBody(statusCode: HttpStatusCode.BadRequest, Summary = "Invalid switch", Description = "Switch parameter is not valid")] + public async Task GetDummies( + [HttpTrigger(AuthorizationLevel.Function, "GET", Route = "dummies")] HttpRequest req, + ILogger log) + { + var content = new List() + { + new DummyResponseModel(), + }; + var result = new OkObjectResult(content); + + return await Task.FromResult(result).ConfigureAwait(false); + } + + [FunctionName(nameof(DummyHttpTrigger.AddDummy))] + [OpenApiOperation(operationId: "addDummy", tags: new[] { "dummy" }, Summary = "Adds a dummy", Description = "This adds a dummy.", Visibility = OpenApiVisibilityType.Advanced)] + [OpenApiRequestBody(contentType: "application/json", bodyType: typeof(DummyRequestModel), Required = true, Description = "Dummy request model")] + [OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(DummyResponseModel), Summary = "Dummy response", Description = "This returns the dummy response")] + [OpenApiResponseWithoutBody(statusCode: HttpStatusCode.BadRequest, Summary = "Invalid request payload", Description = "Request payload is not valid")] + public async Task AddDummy( + [HttpTrigger(AuthorizationLevel.Function, "POST", Route = "dummies")] HttpRequest req, + ILogger log) + { + var content = new DummyResponseModel(); + var result = new OkObjectResult(content); + + return await Task.FromResult(result).ConfigureAwait(false); + } + } +} diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV2IoC/PetStoreHttpTrigger.cs b/samples/Aliencube.AzureFunctions.FunctionAppV2IoC/PetStoreHttpTrigger.cs index 78c4829..8b268d2 100644 --- a/samples/Aliencube.AzureFunctions.FunctionAppV2IoC/PetStoreHttpTrigger.cs +++ b/samples/Aliencube.AzureFunctions.FunctionAppV2IoC/PetStoreHttpTrigger.cs @@ -3,8 +3,8 @@ using System.Net; using System.Threading.Tasks; -using Aliencube.AzureFunctions.Extensions.OpenApi.Attributes; -using Aliencube.AzureFunctions.Extensions.OpenApi.Enums; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums; using Aliencube.AzureFunctions.FunctionApp.Models; using Aliencube.AzureFunctions.FunctionApp.Services; @@ -19,9 +19,9 @@ namespace Aliencube.AzureFunctions.FunctionAppV2IoC { public class PetStoreHttpTrigger { - private readonly ISampleHttpService _service; + private readonly IDummyHttpService _service; - public PetStoreHttpTrigger(ISampleHttpService service) + public PetStoreHttpTrigger(IDummyHttpService service) { this._service = service ?? throw new ArgumentNullException(nameof(service)); } diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV2IoC/SampleHttpTrigger.cs b/samples/Aliencube.AzureFunctions.FunctionAppV2IoC/SampleHttpTrigger.cs deleted file mode 100644 index e751f75..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionAppV2IoC/SampleHttpTrigger.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net; -using System.Threading.Tasks; - -using Aliencube.AzureFunctions.Extensions.OpenApi.Attributes; -using Aliencube.AzureFunctions.Extensions.OpenApi.Enums; -using Aliencube.AzureFunctions.FunctionApp.Models; -using Aliencube.AzureFunctions.FunctionApp.Services; - -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Microsoft.Azure.WebJobs; -using Microsoft.Azure.WebJobs.Extensions.Http; -using Microsoft.Extensions.Logging; - -namespace Aliencube.AzureFunctions.FunctionAppV2IoC -{ - public class SampleHttpTrigger - { - private readonly ISampleHttpService _service; - - public SampleHttpTrigger(ISampleHttpService service) - { - this._service = service ?? throw new ArgumentNullException(nameof(service)); - } - - [FunctionName(nameof(SampleHttpTrigger.GetSamples))] - [OpenApiOperation(operationId: "list", tags: new[] { "sample" }, Summary = "Gets the list of samples", Description = "This gets the list of samples.", Visibility = OpenApiVisibilityType.Important)] - [OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(List), Summary = "List of the sample responses")] - public async Task GetSamples( - [HttpTrigger(AuthorizationLevel.Function, "get", Route = "samples")] HttpRequest req, - ILogger log) - { - var content = await this._service.GetSamples().ConfigureAwait(false); - var result = new OkObjectResult(content); - - return result; - } - } -} diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV2IoC/StartUp.cs b/samples/Aliencube.AzureFunctions.FunctionAppV2IoC/StartUp.cs index 575575a..5bb227a 100644 --- a/samples/Aliencube.AzureFunctions.FunctionAppV2IoC/StartUp.cs +++ b/samples/Aliencube.AzureFunctions.FunctionAppV2IoC/StartUp.cs @@ -14,7 +14,7 @@ public class StartUp : FunctionsStartup /// public override void Configure(IFunctionsHostBuilder builder) { - builder.Services.AddTransient(); + builder.Services.AddTransient(); } } } diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV2Static/Aliencube.AzureFunctions.FunctionAppV2Static.csproj b/samples/Aliencube.AzureFunctions.FunctionAppV2Static/Aliencube.AzureFunctions.FunctionAppV2Static.csproj index 6971207..91689c2 100644 --- a/samples/Aliencube.AzureFunctions.FunctionAppV2Static/Aliencube.AzureFunctions.FunctionAppV2Static.csproj +++ b/samples/Aliencube.AzureFunctions.FunctionAppV2Static/Aliencube.AzureFunctions.FunctionAppV2Static.csproj @@ -6,7 +6,7 @@ - + diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV2Static/DummyHttpTrigger.cs b/samples/Aliencube.AzureFunctions.FunctionAppV2Static/DummyHttpTrigger.cs new file mode 100644 index 0000000..1bc0952 --- /dev/null +++ b/samples/Aliencube.AzureFunctions.FunctionAppV2Static/DummyHttpTrigger.cs @@ -0,0 +1,55 @@ +using System.Collections.Generic; +using System.Net; +using System.Threading.Tasks; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums; +using Aliencube.AzureFunctions.FunctionApp.Models; + +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Azure.WebJobs; +using Microsoft.Azure.WebJobs.Extensions.Http; +using Microsoft.Extensions.Logging; +using Microsoft.OpenApi.Models; + +namespace Aliencube.AzureFunctions.FunctionAppV2Static +{ + public static class DummyHttpTrigger + { + [FunctionName(nameof(DummyHttpTrigger.GetDummies))] + [OpenApiOperation(operationId: "getDummies", tags: new[] { "dummy" }, Summary = "Gets the list of dummies", Description = "This gets the list of dummies.", Visibility = OpenApiVisibilityType.Important)] + [OpenApiParameter(name: "name", In = ParameterLocation.Query, Required = true, Type = typeof(string), Summary = "Dummy name", Description = "Dummy name", Visibility = OpenApiVisibilityType.Important)] + [OpenApiParameter(name: "switch", In = ParameterLocation.Path, Required = true, Type = typeof(StringEnum), Summary = "Dummy switch", Description = "Dummy switch", Visibility = OpenApiVisibilityType.Important)] + [OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(List), Summary = "List of the dummy responses", Description = "This returns the list of dummy responses")] + [OpenApiResponseWithoutBody(statusCode: HttpStatusCode.NotFound, Summary = "Name not found", Description = "Name parameter is not found")] + [OpenApiResponseWithoutBody(statusCode: HttpStatusCode.BadRequest, Summary = "Invalid switch", Description = "Switch parameter is not valid")] + public static async Task GetDummies( + [HttpTrigger(AuthorizationLevel.Function, "GET", Route = "dummies")] HttpRequest req, + ILogger log) + { + var content = new List() + { + new DummyResponseModel(), + }; + var result = new OkObjectResult(content); + + return await Task.FromResult(result).ConfigureAwait(false); + } + + [FunctionName(nameof(DummyHttpTrigger.AddDummy))] + [OpenApiOperation(operationId: "addDummy", tags: new[] { "dummy" }, Summary = "Adds a dummy", Description = "This adds a dummy.", Visibility = OpenApiVisibilityType.Advanced)] + [OpenApiRequestBody(contentType: "application/json", bodyType: typeof(DummyRequestModel), Required = true, Description = "Dummy request model")] + [OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(DummyResponseModel), Summary = "Dummy response", Description = "This returns the dummy response")] + [OpenApiResponseWithoutBody(statusCode: HttpStatusCode.BadRequest, Summary = "Invalid request payload", Description = "Request payload is not valid")] + public static async Task AddDummy( + [HttpTrigger(AuthorizationLevel.Function, "POST", Route = "dummies")] HttpRequest req, + ILogger log) + { + var content = new DummyResponseModel(); + var result = new OkObjectResult(content); + + return await Task.FromResult(result).ConfigureAwait(false); + } + } +} diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV2Static/PetStoreHttpTrigger.cs b/samples/Aliencube.AzureFunctions.FunctionAppV2Static/PetStoreHttpTrigger.cs index a1ce127..c488da1 100644 --- a/samples/Aliencube.AzureFunctions.FunctionAppV2Static/PetStoreHttpTrigger.cs +++ b/samples/Aliencube.AzureFunctions.FunctionAppV2Static/PetStoreHttpTrigger.cs @@ -2,8 +2,8 @@ using System.Net; using System.Threading.Tasks; -using Aliencube.AzureFunctions.Extensions.OpenApi.Attributes; -using Aliencube.AzureFunctions.Extensions.OpenApi.Enums; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums; using Aliencube.AzureFunctions.FunctionApp.Models; using Microsoft.AspNetCore.Http; diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV2Static/SampleHttpTrigger.cs b/samples/Aliencube.AzureFunctions.FunctionAppV2Static/SampleHttpTrigger.cs deleted file mode 100644 index c568de1..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionAppV2Static/SampleHttpTrigger.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Collections.Generic; -using System.Net; -using System.Threading.Tasks; - -using Aliencube.AzureFunctions.Extensions.OpenApi.Attributes; -using Aliencube.AzureFunctions.Extensions.OpenApi.Enums; -using Aliencube.AzureFunctions.FunctionApp.Models; - -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Microsoft.Azure.WebJobs; -using Microsoft.Azure.WebJobs.Extensions.Http; -using Microsoft.Extensions.Logging; - -namespace Aliencube.AzureFunctions.FunctionAppV2Static -{ - public static class SampleHttpTrigger - { - [FunctionName(nameof(SampleHttpTrigger.GetSamples))] - [OpenApiOperation(operationId: "list", tags: new[] { "sample" }, Summary = "Gets the list of samples", Description = "This gets the list of samples.", Visibility = OpenApiVisibilityType.Important)] - [OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(List), Summary = "List of the sample responses")] - public static async Task GetSamples( - [HttpTrigger(AuthorizationLevel.Function, "get", Route = "samples")] HttpRequest req, - ILogger log) - { - var content = new List() - { - new SampleResponseModel(), - }; - var result = new OkObjectResult(content); - - return await Task.FromResult(result).ConfigureAwait(false); - } - } -} diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV3/.gitignore b/samples/Aliencube.AzureFunctions.FunctionAppV3/.gitignore deleted file mode 100644 index ad9b6e1..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionAppV3/.gitignore +++ /dev/null @@ -1,264 +0,0 @@ -## Ignore Visual Studio temporary files, build results, and -## files generated by popular Visual Studio add-ons. - -# Azure Functions localsettings file -# local.settings.json - -# User-specific files -*.suo -*.user -*.userosscache -*.sln.docstates - -# User-specific files (MonoDevelop/Xamarin Studio) -*.userprefs - -# Build results -[Dd]ebug/ -[Dd]ebugPublic/ -[Rr]elease/ -[Rr]eleases/ -x64/ -x86/ -bld/ -[Bb]in/ -[Oo]bj/ -[Ll]og/ - -# Visual Studio 2015 cache/options directory -.vs/ -# Uncomment if you have tasks that create the project's static files in wwwroot -#wwwroot/ - -# MSTest test Results -[Tt]est[Rr]esult*/ -[Bb]uild[Ll]og.* - -# NUNIT -*.VisualState.xml -TestResult.xml - -# Build Results of an ATL Project -[Dd]ebugPS/ -[Rr]eleasePS/ -dlldata.c - -# DNX -project.lock.json -project.fragment.lock.json -artifacts/ - -*_i.c -*_p.c -*_i.h -*.ilk -*.meta -*.obj -*.pch -*.pdb -*.pgc -*.pgd -*.rsp -*.sbr -*.tlb -*.tli -*.tlh -*.tmp -*.tmp_proj -*.log -*.vspscc -*.vssscc -.builds -*.pidb -*.svclog -*.scc - -# Chutzpah Test files -_Chutzpah* - -# Visual C++ cache files -ipch/ -*.aps -*.ncb -*.opendb -*.opensdf -*.sdf -*.cachefile -*.VC.db -*.VC.VC.opendb - -# Visual Studio profiler -*.psess -*.vsp -*.vspx -*.sap - -# TFS 2012 Local Workspace -$tf/ - -# Guidance Automation Toolkit -*.gpState - -# ReSharper is a .NET coding add-in -_ReSharper*/ -*.[Rr]e[Ss]harper -*.DotSettings.user - -# JustCode is a .NET coding add-in -.JustCode - -# TeamCity is a build add-in -_TeamCity* - -# DotCover is a Code Coverage Tool -*.dotCover - -# NCrunch -_NCrunch_* -.*crunch*.local.xml -nCrunchTemp_* - -# MightyMoose -*.mm.* -AutoTest.Net/ - -# Web workbench (sass) -.sass-cache/ - -# Installshield output folder -[Ee]xpress/ - -# DocProject is a documentation generator add-in -DocProject/buildhelp/ -DocProject/Help/*.HxT -DocProject/Help/*.HxC -DocProject/Help/*.hhc -DocProject/Help/*.hhk -DocProject/Help/*.hhp -DocProject/Help/Html2 -DocProject/Help/html - -# Click-Once directory -publish/ - -# Publish Web Output -*.[Pp]ublish.xml -*.azurePubxml -# TODO: Comment the next line if you want to checkin your web deploy settings -# but database connection strings (with potential passwords) will be unencrypted -#*.pubxml -*.publishproj - -# Microsoft Azure Web App publish settings. Comment the next line if you want to -# checkin your Azure Web App publish settings, but sensitive information contained -# in these scripts will be unencrypted -PublishScripts/ - -# NuGet Packages -*.nupkg -# The packages folder can be ignored because of Package Restore -**/packages/* -# except build/, which is used as an MSBuild target. -!**/packages/build/ -# Uncomment if necessary however generally it will be regenerated when needed -#!**/packages/repositories.config -# NuGet v3's project.json files produces more ignoreable files -*.nuget.props -*.nuget.targets - -# Microsoft Azure Build Output -csx/ -*.build.csdef - -# Microsoft Azure Emulator -ecf/ -rcf/ - -# Windows Store app package directories and files -AppPackages/ -BundleArtifacts/ -Package.StoreAssociation.xml -_pkginfo.txt - -# Visual Studio cache files -# files ending in .cache can be ignored -*.[Cc]ache -# but keep track of directories ending in .cache -!*.[Cc]ache/ - -# Others -ClientBin/ -~$* -*~ -*.dbmdl -*.dbproj.schemaview -*.jfm -*.pfx -*.publishsettings -node_modules/ -orleans.codegen.cs - -# Since there are multiple workflows, uncomment next line to ignore bower_components -# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) -#bower_components/ - -# RIA/Silverlight projects -Generated_Code/ - -# Backup & report files from converting an old project file -# to a newer Visual Studio version. Backup files are not needed, -# because we have git ;-) -_UpgradeReport_Files/ -Backup*/ -UpgradeLog*.XML -UpgradeLog*.htm - -# SQL Server files -*.mdf -*.ldf - -# Business Intelligence projects -*.rdl.data -*.bim.layout -*.bim_*.settings - -# Microsoft Fakes -FakesAssemblies/ - -# GhostDoc plugin setting file -*.GhostDoc.xml - -# Node.js Tools for Visual Studio -.ntvs_analysis.dat - -# Visual Studio 6 build log -*.plg - -# Visual Studio 6 workspace options file -*.opt - -# Visual Studio LightSwitch build output -**/*.HTMLClient/GeneratedArtifacts -**/*.DesktopClient/GeneratedArtifacts -**/*.DesktopClient/ModelManifest.xml -**/*.Server/GeneratedArtifacts -**/*.Server/ModelManifest.xml -_Pvt_Extensions - -# Paket dependency manager -.paket/paket.exe -paket-files/ - -# FAKE - F# Make -.fake/ - -# JetBrains Rider -.idea/ -*.sln.iml - -# CodeRush -.cr/ - -# Python Tools for Visual Studio (PTVS) -__pycache__/ -*.pyc \ No newline at end of file diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV3/.vscode/extensions.json b/samples/Aliencube.AzureFunctions.FunctionAppV3/.vscode/extensions.json deleted file mode 100644 index dde673d..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionAppV3/.vscode/extensions.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "recommendations": [ - "ms-azuretools.vscode-azurefunctions" - ] -} \ No newline at end of file diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV3/Aliencube.AzureFunctions.FunctionAppV3.csproj b/samples/Aliencube.AzureFunctions.FunctionAppV3/Aliencube.AzureFunctions.FunctionAppV3.csproj deleted file mode 100644 index 5417576..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionAppV3/Aliencube.AzureFunctions.FunctionAppV3.csproj +++ /dev/null @@ -1,31 +0,0 @@ - - - - netcoreapp3.1 - v3 - - - - - - - - - - - - - - - PreserveNewest - - - PreserveNewest - Never - - - PreserveNewest - - - - \ No newline at end of file diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV3/OpenApiHttpTrigger.cs b/samples/Aliencube.AzureFunctions.FunctionAppV3/OpenApiHttpTrigger.cs deleted file mode 100644 index b4afff5..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionAppV3/OpenApiHttpTrigger.cs +++ /dev/null @@ -1,103 +0,0 @@ -using System; -using System.Reflection; -using System.Threading.Tasks; - -using Aliencube.AzureFunctions.Extensions.DependencyInjection.Extensions; -using Aliencube.AzureFunctions.Extensions.OpenApi.Attributes; -using Aliencube.AzureFunctions.FunctionAppCommon.Functions; -using Aliencube.AzureFunctions.FunctionAppCommon.Functions.FunctionOptions; - -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Microsoft.Azure.WebJobs; -using Microsoft.Azure.WebJobs.Extensions.Http; -using Microsoft.Extensions.Logging; - -namespace Aliencube.AzureFunctions.FunctionAppV3 -{ - /// - /// This represents the HTTP trigger for Open API. - /// - public class OpenApiHttpTrigger - { - private readonly IRenderOpeApiDocumentFunction _docFunction; - private readonly IRenderSwaggerUIFunction _suiFunction; - - /// - /// Initializes a new instance of the class. - /// - /// instance. - /// instance. - public OpenApiHttpTrigger(IRenderOpeApiDocumentFunction docFunction, IRenderSwaggerUIFunction suiFunction) - { - this._docFunction = docFunction ?? throw new ArgumentNullException(nameof(docFunction)); - this._suiFunction = suiFunction ?? throw new ArgumentNullException(nameof(suiFunction)); - } - - /// - /// Invokes the HTTP trigger endpoint to get Open API document. - /// - /// instance. - /// File extension representing the document format. This MUST be either "json" or "yaml". - /// instance. - /// Open API document in a format of either JSON or YAML. - [FunctionName(nameof(RenderSwaggerDocument))] - [OpenApiIgnore] - public async Task RenderSwaggerDocument( - [HttpTrigger(AuthorizationLevel.Function, "get", Route = "swagger.{extension}")] HttpRequest req, - string extension, - ILogger log) - { - var options = new RenderOpeApiDocumentFunctionOptions("v2", extension, Assembly.GetExecutingAssembly()); - var result = await this._docFunction.AddLogger(log) - .InvokeAsync(req, options) - .ConfigureAwait(false); - - return result; - } - - /// - /// Invokes the HTTP trigger endpoint to get Open API document. - /// - /// instance. - /// Open API document spec version. This MUST be either "v2" or "v3". - /// File extension representing the document format. This MUST be either "json" or "yaml". - /// instance. - /// Open API document in a format of either JSON or YAML. - [FunctionName(nameof(RenderOpenApiDocument))] - [OpenApiIgnore] - public async Task RenderOpenApiDocument( - [HttpTrigger(AuthorizationLevel.Function, "get", Route = "openapi/{version}.{extension}")] HttpRequest req, - string version, - string extension, - ILogger log) - { - var options = new RenderOpeApiDocumentFunctionOptions(version, extension, Assembly.GetExecutingAssembly()); - var result = await this._docFunction.AddLogger(log) - .InvokeAsync(req, options) - .ConfigureAwait(false); - - return result; - } - - /// - /// Invokes the HTTP trigger endpoint to render Swagger UI in HTML. - /// - /// instance. - /// instance. - /// Swagger UI in HTML. - [FunctionName(nameof(RenderSwaggerUI))] - [OpenApiIgnore] - public async Task RenderSwaggerUI( - [HttpTrigger(AuthorizationLevel.Function, "get", Route = "swagger/ui")] HttpRequest req, - ILogger log) - { - var options = new RenderSwaggerUIFunctionOptions(); - var result = await this._suiFunction.AddLogger(log) - .InvokeAsync(req, options) - .ConfigureAwait(false); - - return result; - } - } -} \ No newline at end of file diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV3/SampleHttpTrigger.cs b/samples/Aliencube.AzureFunctions.FunctionAppV3/SampleHttpTrigger.cs deleted file mode 100644 index 0c90093..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionAppV3/SampleHttpTrigger.cs +++ /dev/null @@ -1,176 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net; -using System.Threading.Tasks; - -using Aliencube.AzureFunctions.Extensions.DependencyInjection.Extensions; -using Aliencube.AzureFunctions.Extensions.OpenApi.Attributes; -using Aliencube.AzureFunctions.Extensions.OpenApi.Enums; -using Aliencube.AzureFunctions.FunctionAppCommon.Functions; -using Aliencube.AzureFunctions.FunctionAppCommon.Models; - -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Microsoft.Azure.WebJobs; -using Microsoft.Azure.WebJobs.Extensions.Http; -using Microsoft.Extensions.Logging; -using Microsoft.OpenApi.Models; - -namespace Aliencube.AzureFunctions.FunctionAppV3 -{ - /// - /// This represents the HTTP trigger. - /// - public class SampleHttpTrigger - { - private readonly ISampleHttpFunction _function; - - /// - /// Initializes a new instance of the class. - /// - /// instance. - public SampleHttpTrigger(ISampleHttpFunction function) - { - this._function = function ?? throw new ArgumentNullException(nameof(function)); - } - - /// - /// Invokes the HTTP trigger endpoint to get sample. - /// - /// instance. - /// instance. - /// instance. - [FunctionName(nameof(SampleHttpTrigger.GetPath))] - [OpenApiOperation(operationId: "path", tags: new[] { "sample" }, Summary = "Gets the list of samples", Description = "This gets the list of samples.", Visibility = OpenApiVisibilityType.Important)] - [OpenApiParameter(name: "id", In = ParameterLocation.Path, Required = true, Type = typeof(int), Summary = "The ID parameter", Visibility = OpenApiVisibilityType.Advanced)] - [OpenApiParameter(name: "category", In = ParameterLocation.Path, Required = true, Type = typeof(string), Summary = "The category parameter", Visibility = OpenApiVisibilityType.Advanced)] - [OpenApiResponseBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(SampleResponseModel), Summary = "Sample response")] - public async Task GetPath( - [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "paths/{id:int}/categories/{category:regex(^[a-z]{{3,}}$)}")] HttpRequest req, - int id, - string category, - ILogger log) - { - var result = await this._function.AddLogger(log) - .InvokeAsync(req) - .ConfigureAwait(false); - - return result; - } - - /// - /// Invokes the HTTP trigger endpoint to get sample. - /// - /// instance. - /// instance. - /// instance. - [FunctionName(nameof(SampleHttpTrigger.GetQuery))] - [OpenApiOperation(operationId: "query", tags: new[] { "sample" }, Summary = "Gets the list of samples", Description = "This gets the list of samples.", Visibility = OpenApiVisibilityType.Important)] - [OpenApiParameter(name: "name", In = ParameterLocation.Query, Required = true, Type = typeof(string), Summary = "The name query key", Visibility = OpenApiVisibilityType.Advanced)] - [OpenApiParameter(name: "limit", In = ParameterLocation.Query, Required = false, Type = typeof(int), Description = "The number of samples to return")] - [OpenApiResponseBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(SampleResponseModel), Summary = "Sample response")] - public async Task GetQuery( - [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "queries")] HttpRequest req, - ILogger log) - { - var result = await this._function.AddLogger(log) - .InvokeAsync(req) - .ConfigureAwait(false); - - return result; - } - - /// - /// Invokes the HTTP trigger endpoint to get sample. - /// - /// instance. - /// instance. - /// instance. - [FunctionName(nameof(SampleHttpTrigger.GetListResponse))] - [OpenApiOperation(operationId: "list", tags: new[] { "sample" }, Summary = "Gets the list of samples", Description = "This gets the list of samples.", Visibility = OpenApiVisibilityType.Important)] - [OpenApiResponseBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(SampleResponseModel), Summary = "Sample response")] - [OpenApiResponseBody(statusCode: HttpStatusCode.Created, contentType: "application/json", bodyType: typeof(List), Summary = "Sample response of a List")] - public async Task GetListResponse( - [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "lists")] HttpRequest req, - ILogger log) - { - var result = await this._function.AddLogger(log) - .InvokeAsync(req) - .ConfigureAwait(false); - - return result; - } - - /// - /// Invokes the HTTP trigger endpoint to get sample. - /// - /// instance. - /// instance. - /// instance. - [FunctionName(nameof(SampleHttpTrigger.GetIListResponse))] - [OpenApiOperation(operationId: "ilist", tags: new[] { "sample" }, Summary = "Gets the list of samples", Description = "This gets the list of samples.", Visibility = OpenApiVisibilityType.Important)] - [OpenApiResponseBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(SampleResponseModel), Summary = "Sample response")] - [OpenApiResponseBody(statusCode: HttpStatusCode.Accepted, contentType: "application/json", bodyType: typeof(IList), Summary = "Sample response of a IList")] - public async Task GetIListResponse( - [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "ilists")] HttpRequest req, - ILogger log) - { - var result = await this._function.AddLogger(log) - .InvokeAsync(req) - .ConfigureAwait(false); - - return result; - } - - ///// - ///// Invokes the HTTP trigger endpoint to get sample. - ///// - ///// instance. - ///// instance. - ///// instance. - //[FunctionName(nameof(SampleHttpTrigger.GetListResponse))] - //[OpenApiOperation(operationId: "list", tags: new[] { "sample" }, Summary = "Gets the list of samples", Description = "This gets the list of samples.", Visibility = OpenApiVisibilityType.Important)] - //[OpenApiResponseBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(SampleResponseModel), Summary = "Sample response")] - //[OpenApiResponseBody(statusCode: HttpStatusCode.Created, contentType: "application/json", bodyType: typeof(List), Summary = "Sample response of a List")] - //[OpenApiResponseBody(statusCode: HttpStatusCode.Accepted, contentType: "application/json", bodyType: typeof(IList), Summary = "Sample response of a IList")] - //[OpenApiResponseBody(statusCode: HttpStatusCode.NonAuthoritativeInformation, contentType: "application/json", bodyType: typeof(SampleResponseModel[]), Summary = "Sample response of a Array")] - //[OpenApiResponseBody(statusCode: HttpStatusCode.BadRequest, contentType: "application/json", bodyType: typeof(Dictionary), Summary = "Sample response of a Dictionary")] - //[OpenApiResponseBody(statusCode: HttpStatusCode.Unauthorized, contentType: "application/json", bodyType: typeof(IDictionary), Summary = "Sample response of a IDictionary")] - //[OpenApiResponseBody(statusCode: HttpStatusCode.Forbidden, contentType: "application/json", bodyType: typeof(JObject), Summary = "Sample response of a JObject")] - //[OpenApiResponseBody(statusCode: HttpStatusCode.NotFound, contentType: "application/json", bodyType: typeof(JToken), Summary = "Sample response of a JToken")] - //[OpenApiResponseBody(statusCode: HttpStatusCode.InternalServerError, contentType: "application/json", bodyType: typeof(List), Summary = "Sample response of a List")] - //[OpenApiResponseBody(statusCode: HttpStatusCode.NotImplemented, contentType: "application/json", bodyType: typeof(Dictionary), Summary = "Sample response of a Dictionary")] - //[OpenApiResponseBody(statusCode: HttpStatusCode.BadGateway, contentType: "application/json", bodyType: typeof(SampleGenericResponseModel), Summary = "Sample response of a Generic")] - //public async Task GetListResponse( - // [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "lists")] HttpRequest req, - // ILogger log) - //{ - // var result = await this._function.AddLogger(log) - // .InvokeAsync(req) - // .ConfigureAwait(false); - - // return result; - //} - - /// - /// Invokes the HTTP trigger endpoint to create sample. - /// - /// instance. - /// instance. - /// instance. - [FunctionName(nameof(PostSample))] - [OpenApiOperation(operationId: "add", tags: new[] { "sample" })] - [OpenApiRequestBody(contentType: "application/json", bodyType: typeof(SampleRequestModel))] - [OpenApiResponseBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(SampleResponseModel), Summary = "Sample response")] - public async Task PostSample( - [HttpTrigger(AuthorizationLevel.Function, "post", Route = "samples")] HttpRequest req, - ILogger log) - { - var result = await this._function.AddLogger(log) - .InvokeAsync(req) - .ConfigureAwait(false); - - return result; - } - } -} \ No newline at end of file diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV3/SampleTimerTrigger.cs b/samples/Aliencube.AzureFunctions.FunctionAppV3/SampleTimerTrigger.cs deleted file mode 100644 index f3398ae..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionAppV3/SampleTimerTrigger.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System; -using System.Threading.Tasks; - -using Aliencube.AzureFunctions.Extensions.DependencyInjection.Extensions; -using Aliencube.AzureFunctions.FunctionAppCommon.Functions; -using Aliencube.AzureFunctions.FunctionAppCommon.Functions.FunctionOptions; - -using Microsoft.Azure.WebJobs; -using Microsoft.Extensions.Logging; - -namespace Aliencube.AzureFunctions.FunctionAppV3 -{ - /// - /// This represents the timer trigger. - /// - public class SampleTimerTrigger - { - private readonly ISampleTimerFunction _function; - - /// - /// Initializes a new instance of the class. - /// - /// instance. - public SampleTimerTrigger(ISampleTimerFunction function) - { - this._function = function ?? throw new ArgumentNullException(nameof(function)); - } - - /// - /// Invokes the timer trigger. - /// - /// instance. - /// instance. - /// instance. - /// instance. - [FunctionName(nameof(Run))] - public async Task Run( - [TimerTrigger("0/5 * * * * *")] TimerInfo myTimer, - [Queue("output")] IAsyncCollector collector, - ILogger log) - { - var options = new SampleTimerFunctionOptions() { Collector = collector }; - - var result = await this._function.AddLogger(log) - .InvokeAsync(myTimer, options) - .ConfigureAwait(false); - } - } -} \ No newline at end of file diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV3/StartUp.cs b/samples/Aliencube.AzureFunctions.FunctionAppV3/StartUp.cs deleted file mode 100644 index 3cb201f..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionAppV3/StartUp.cs +++ /dev/null @@ -1,37 +0,0 @@ -using Aliencube.AzureFunctions.Extensions.OpenApi; -using Aliencube.AzureFunctions.Extensions.OpenApi.Abstractions; -using Aliencube.AzureFunctions.Extensions.OpenApi.Configurations; -using Aliencube.AzureFunctions.FunctionAppCommon.Configurations; -using Aliencube.AzureFunctions.FunctionAppCommon.Dependencies; -using Aliencube.AzureFunctions.FunctionAppCommon.Functions; - -using Microsoft.Azure.Functions.Extensions.DependencyInjection; -using Microsoft.Extensions.DependencyInjection; - -[assembly: FunctionsStartup(typeof(Aliencube.AzureFunctions.FunctionAppV3.StartUp))] -namespace Aliencube.AzureFunctions.FunctionAppV3 -{ - /// - /// This represents the entity to be invoked during the runtime startup. - /// - public class StartUp : FunctionsStartup - { - /// - public override void Configure(IFunctionsHostBuilder builder) - { - builder.Services.AddSingleton(); - builder.Services.AddSingleton(); - - builder.Services.AddTransient(); - builder.Services.AddTransient(); - builder.Services.AddTransient(); - - builder.Services.AddTransient(); - builder.Services.AddTransient(); - builder.Services.AddTransient(); - builder.Services.AddTransient(); - - builder.Services.AddTransient(); - } - } -} diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV3/host.json b/samples/Aliencube.AzureFunctions.FunctionAppV3/host.json deleted file mode 100644 index 9f60374..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionAppV3/host.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "version": "2.0", - "logging": { - "applicationInsights": { - "samplingSettings": { - "isEnabled": true, - "excludedTypes": "Request" - } - } - //}, - //"openApi": { - // "info": { - // "version": "3.0.0", - // "title": "Open API Sample on Azure Functions", - // "description": "A sample API that runs on Azure Functions 3.x using Open API specification - from **host.json**.", - // "termsOfService": "https://github.com/aliencube/AzureFunctions.Extensions", - // "contact": { - // "name": "Aliencube Community", - // "email": "no-reply@aliencube.org", - // "url": "https://github.com/aliencube/AzureFunctions.Extensions/issues" - // }, - // "license": { - // "name": "MIT", - // "url": "http://opensource.org/licenses/MIT" - // } - // } - } -} \ No newline at end of file diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV3/local.settings.json b/samples/Aliencube.AzureFunctions.FunctionAppV3/local.settings.json deleted file mode 100644 index ba4324b..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionAppV3/local.settings.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "IsEncrypted": false, - "Values": { - "AzureWebJobsStorage": "UseDevelopmentStorage=true", - "FUNCTIONS_WORKER_RUNTIME": "dotnet", - - "OpenApi__Info__Version": "3.0.0", - "OpenApi__Info__Title": "Open API Sample on Azure Functions", - "OpenApi__Info__Description": "A sample API that runs on Azure Functions 3.x using Open API specification - from **local.settings.json**.", - "OpenApi__Info__TermsOfService": "https://github.com/aliencube/AzureFunctions.Extensions", - "OpenApi__Info__Contact__Name": "Aliencube Community", - "OpenApi__Info__Contact__Email": "no-reply@aliencube.org", - "OpenApi__Info__Contact__Url": "https://github.com/aliencube/AzureFunctions.Extensions/issues", - "OpenApi__Info__License__Name": "MIT", - "OpenApi__Info__License__Url": "http://opensource.org/licenses/MIT", - - "OpenApi__ApiKey": "" - } -} \ No newline at end of file diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV3/openapisettings.json b/samples/Aliencube.AzureFunctions.FunctionAppV3/openapisettings.json deleted file mode 100644 index d9b9a52..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionAppV3/openapisettings.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - //"info": { - // "version": "3.0.0", - // "title": "Open API Sample on Azure Functions", - // "description": "A sample API that runs on Azure Functions 3.x using Open API specification - from **openapisettings.json**.", - // "termsOfService": "https://github.com/aliencube/AzureFunctions.Extensions", - // "contact": { - // "name": "Aliencube Community", - // "email": "no-reply@aliencube.org", - // "url": "https://github.com/aliencube/AzureFunctions.Extensions/issues" - // }, - // "license": { - // "name": "MIT", - // "url": "http://opensource.org/licenses/MIT" - // } - //} -} \ No newline at end of file diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV3IoC/Aliencube.AzureFunctions.FunctionAppV3IoC.csproj b/samples/Aliencube.AzureFunctions.FunctionAppV3IoC/Aliencube.AzureFunctions.FunctionAppV3IoC.csproj index 5c1d038..504f006 100644 --- a/samples/Aliencube.AzureFunctions.FunctionAppV3IoC/Aliencube.AzureFunctions.FunctionAppV3IoC.csproj +++ b/samples/Aliencube.AzureFunctions.FunctionAppV3IoC/Aliencube.AzureFunctions.FunctionAppV3IoC.csproj @@ -6,7 +6,7 @@ - + diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV3IoC/DummyHttpTrigger.cs b/samples/Aliencube.AzureFunctions.FunctionAppV3IoC/DummyHttpTrigger.cs new file mode 100644 index 0000000..fdcb7df --- /dev/null +++ b/samples/Aliencube.AzureFunctions.FunctionAppV3IoC/DummyHttpTrigger.cs @@ -0,0 +1,64 @@ +using System; +using System.Collections.Generic; +using System.Net; +using System.Threading.Tasks; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums; +using Aliencube.AzureFunctions.FunctionApp.Models; +using Aliencube.AzureFunctions.FunctionApp.Services; + +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Azure.WebJobs; +using Microsoft.Azure.WebJobs.Extensions.Http; +using Microsoft.Extensions.Logging; +using Microsoft.OpenApi.Models; + +namespace Aliencube.AzureFunctions.FunctionAppV3IoC +{ + public class DummyHttpTrigger + { + private readonly IDummyHttpService _service; + + public DummyHttpTrigger(IDummyHttpService service) + { + this._service = service ?? throw new ArgumentNullException(nameof(service)); + } + + [FunctionName(nameof(DummyHttpTrigger.GetDummies))] + [OpenApiOperation(operationId: "getDummies", tags: new[] { "dummy" }, Summary = "Gets the list of dummies", Description = "This gets the list of dummies.", Visibility = OpenApiVisibilityType.Important)] + [OpenApiParameter(name: "name", In = ParameterLocation.Query, Required = true, Type = typeof(string), Summary = "Dummy name", Description = "Dummy name", Visibility = OpenApiVisibilityType.Important)] + [OpenApiParameter(name: "switch", In = ParameterLocation.Path, Required = true, Type = typeof(StringEnum), Summary = "Dummy switch", Description = "Dummy switch", Visibility = OpenApiVisibilityType.Important)] + [OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(List), Summary = "List of the dummy responses", Description = "This returns the list of dummy responses")] + [OpenApiResponseWithoutBody(statusCode: HttpStatusCode.NotFound, Summary = "Name not found", Description = "Name parameter is not found")] + [OpenApiResponseWithoutBody(statusCode: HttpStatusCode.BadRequest, Summary = "Invalid switch", Description = "Switch parameter is not valid")] + public async Task GetDummies( + [HttpTrigger(AuthorizationLevel.Function, "GET", Route = "dummies")] HttpRequest req, + ILogger log) + { + var content = new List() + { + new DummyResponseModel(), + }; + var result = new OkObjectResult(content); + + return await Task.FromResult(result).ConfigureAwait(false); + } + + [FunctionName(nameof(DummyHttpTrigger.AddDummy))] + [OpenApiOperation(operationId: "addDummy", tags: new[] { "dummy" }, Summary = "Adds a dummy", Description = "This adds a dummy.", Visibility = OpenApiVisibilityType.Advanced)] + [OpenApiRequestBody(contentType: "application/json", bodyType: typeof(DummyRequestModel), Required = true, Description = "Dummy request model")] + [OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(DummyResponseModel), Summary = "Dummy response", Description = "This returns the dummy response")] + [OpenApiResponseWithoutBody(statusCode: HttpStatusCode.BadRequest, Summary = "Invalid request payload", Description = "Request payload is not valid")] + public async Task AddDummy( + [HttpTrigger(AuthorizationLevel.Function, "POST", Route = "dummies")] HttpRequest req, + ILogger log) + { + var content = new DummyResponseModel(); + var result = new OkObjectResult(content); + + return await Task.FromResult(result).ConfigureAwait(false); + } + } +} diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV3IoC/PetStoreHttpTrigger.cs b/samples/Aliencube.AzureFunctions.FunctionAppV3IoC/PetStoreHttpTrigger.cs index 437f9fa..0f3fc11 100644 --- a/samples/Aliencube.AzureFunctions.FunctionAppV3IoC/PetStoreHttpTrigger.cs +++ b/samples/Aliencube.AzureFunctions.FunctionAppV3IoC/PetStoreHttpTrigger.cs @@ -3,8 +3,8 @@ using System.Net; using System.Threading.Tasks; -using Aliencube.AzureFunctions.Extensions.OpenApi.Attributes; -using Aliencube.AzureFunctions.Extensions.OpenApi.Enums; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums; using Aliencube.AzureFunctions.FunctionApp.Models; using Aliencube.AzureFunctions.FunctionApp.Services; @@ -19,9 +19,9 @@ namespace Aliencube.AzureFunctions.FunctionAppV3IoC { public class PetStoreHttpTrigger { - private readonly ISampleHttpService _service; + private readonly IDummyHttpService _service; - public PetStoreHttpTrigger(ISampleHttpService service) + public PetStoreHttpTrigger(IDummyHttpService service) { this._service = service ?? throw new ArgumentNullException(nameof(service)); } diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV3IoC/SampleHttpTrigger.cs b/samples/Aliencube.AzureFunctions.FunctionAppV3IoC/SampleHttpTrigger.cs deleted file mode 100644 index 119edce..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionAppV3IoC/SampleHttpTrigger.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net; -using System.Threading.Tasks; - -using Aliencube.AzureFunctions.Extensions.OpenApi.Attributes; -using Aliencube.AzureFunctions.Extensions.OpenApi.Enums; -using Aliencube.AzureFunctions.FunctionApp.Models; -using Aliencube.AzureFunctions.FunctionApp.Services; - -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Microsoft.Azure.WebJobs; -using Microsoft.Azure.WebJobs.Extensions.Http; -using Microsoft.Extensions.Logging; - -namespace Aliencube.AzureFunctions.FunctionAppV3IoC -{ - public class SampleHttpTrigger - { - private readonly ISampleHttpService _service; - - public SampleHttpTrigger(ISampleHttpService service) - { - this._service = service ?? throw new ArgumentNullException(nameof(service)); - } - - [FunctionName(nameof(SampleHttpTrigger.GetSamples))] - [OpenApiOperation(operationId: "list", tags: new[] { "sample" }, Summary = "Gets the list of samples", Description = "This gets the list of samples.", Visibility = OpenApiVisibilityType.Important)] - [OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(List), Summary = "List of the sample responses")] - public async Task GetSamples( - [HttpTrigger(AuthorizationLevel.Function, "get", Route = "samples")] HttpRequest req, - ILogger log) - { - var content = await this._service.GetSamples().ConfigureAwait(false); - var result = new OkObjectResult(content); - - return result; - } - } -} diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV3IoC/StartUp.cs b/samples/Aliencube.AzureFunctions.FunctionAppV3IoC/StartUp.cs index 94e9dfb..ccf8c1c 100644 --- a/samples/Aliencube.AzureFunctions.FunctionAppV3IoC/StartUp.cs +++ b/samples/Aliencube.AzureFunctions.FunctionAppV3IoC/StartUp.cs @@ -14,7 +14,7 @@ public class StartUp : FunctionsStartup /// public override void Configure(IFunctionsHostBuilder builder) { - builder.Services.AddTransient(); + builder.Services.AddTransient(); } } } diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV3Static/Aliencube.AzureFunctions.FunctionAppV3Static.csproj b/samples/Aliencube.AzureFunctions.FunctionAppV3Static/Aliencube.AzureFunctions.FunctionAppV3Static.csproj index cf78c88..68da5ec 100644 --- a/samples/Aliencube.AzureFunctions.FunctionAppV3Static/Aliencube.AzureFunctions.FunctionAppV3Static.csproj +++ b/samples/Aliencube.AzureFunctions.FunctionAppV3Static/Aliencube.AzureFunctions.FunctionAppV3Static.csproj @@ -6,7 +6,7 @@ - + diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV3Static/DummyHttpTrigger.cs b/samples/Aliencube.AzureFunctions.FunctionAppV3Static/DummyHttpTrigger.cs new file mode 100644 index 0000000..0bd9edd --- /dev/null +++ b/samples/Aliencube.AzureFunctions.FunctionAppV3Static/DummyHttpTrigger.cs @@ -0,0 +1,55 @@ +using System.Collections.Generic; +using System.Net; +using System.Threading.Tasks; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums; +using Aliencube.AzureFunctions.FunctionApp.Models; + +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Azure.WebJobs; +using Microsoft.Azure.WebJobs.Extensions.Http; +using Microsoft.Extensions.Logging; +using Microsoft.OpenApi.Models; + +namespace Aliencube.AzureFunctions.FunctionAppV3Static +{ + public static class DummyHttpTrigger + { + [FunctionName(nameof(DummyHttpTrigger.GetDummies))] + [OpenApiOperation(operationId: "getDummies", tags: new[] { "dummy" }, Summary = "Gets the list of dummies", Description = "This gets the list of dummies.", Visibility = OpenApiVisibilityType.Important)] + [OpenApiParameter(name: "name", In = ParameterLocation.Query, Required = true, Type = typeof(string), Summary = "Dummy name", Description = "Dummy name", Visibility = OpenApiVisibilityType.Important)] + [OpenApiParameter(name: "switch", In = ParameterLocation.Path, Required = true, Type = typeof(StringEnum), Summary = "Dummy switch", Description = "Dummy switch", Visibility = OpenApiVisibilityType.Important)] + [OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(List), Summary = "List of the dummy responses", Description = "This returns the list of dummy responses")] + [OpenApiResponseWithoutBody(statusCode: HttpStatusCode.NotFound, Summary = "Name not found", Description = "Name parameter is not found")] + [OpenApiResponseWithoutBody(statusCode: HttpStatusCode.BadRequest, Summary = "Invalid switch", Description = "Switch parameter is not valid")] + public static async Task GetDummies( + [HttpTrigger(AuthorizationLevel.Function, "GET", Route = "dummies")] HttpRequest req, + ILogger log) + { + var content = new List() + { + new DummyResponseModel(), + }; + var result = new OkObjectResult(content); + + return await Task.FromResult(result).ConfigureAwait(false); + } + + [FunctionName(nameof(DummyHttpTrigger.AddDummy))] + [OpenApiOperation(operationId: "addDummy", tags: new[] { "dummy" }, Summary = "Adds a dummy", Description = "This adds a dummy.", Visibility = OpenApiVisibilityType.Advanced)] + [OpenApiRequestBody(contentType: "application/json", bodyType: typeof(DummyRequestModel), Required = true, Description = "Dummy request model")] + [OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(DummyResponseModel), Summary = "Dummy response", Description = "This returns the dummy response")] + [OpenApiResponseWithoutBody(statusCode: HttpStatusCode.BadRequest, Summary = "Invalid request payload", Description = "Request payload is not valid")] + public static async Task AddDummy( + [HttpTrigger(AuthorizationLevel.Function, "POST", Route = "dummies")] HttpRequest req, + ILogger log) + { + var content = new DummyResponseModel(); + var result = new OkObjectResult(content); + + return await Task.FromResult(result).ConfigureAwait(false); + } + } +} diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV3Static/PetStoreHttpTrigger.cs b/samples/Aliencube.AzureFunctions.FunctionAppV3Static/PetStoreHttpTrigger.cs index 720d6f1..a385af2 100644 --- a/samples/Aliencube.AzureFunctions.FunctionAppV3Static/PetStoreHttpTrigger.cs +++ b/samples/Aliencube.AzureFunctions.FunctionAppV3Static/PetStoreHttpTrigger.cs @@ -2,8 +2,8 @@ using System.Net; using System.Threading.Tasks; -using Aliencube.AzureFunctions.Extensions.OpenApi.Attributes; -using Aliencube.AzureFunctions.Extensions.OpenApi.Enums; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums; using Aliencube.AzureFunctions.FunctionApp.Models; using Microsoft.AspNetCore.Http; diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV3Static/SampleHttpTrigger.cs b/samples/Aliencube.AzureFunctions.FunctionAppV3Static/SampleHttpTrigger.cs deleted file mode 100644 index 30eb0fc..0000000 --- a/samples/Aliencube.AzureFunctions.FunctionAppV3Static/SampleHttpTrigger.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Collections.Generic; -using System.Net; -using System.Threading.Tasks; - -using Aliencube.AzureFunctions.Extensions.OpenApi.Attributes; -using Aliencube.AzureFunctions.Extensions.OpenApi.Enums; -using Aliencube.AzureFunctions.FunctionApp.Models; - -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Microsoft.Azure.WebJobs; -using Microsoft.Azure.WebJobs.Extensions.Http; -using Microsoft.Extensions.Logging; - -namespace Aliencube.AzureFunctions.FunctionAppV3Static -{ - public static class SampleHttpTrigger - { - [FunctionName(nameof(SampleHttpTrigger.GetSamples))] - [OpenApiOperation(operationId: "list", tags: new[] { "sample" }, Summary = "Gets the list of samples", Description = "This gets the list of samples.", Visibility = OpenApiVisibilityType.Important)] - [OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(List), Summary = "List of the sample responses")] - public static async Task GetSamples( - [HttpTrigger(AuthorizationLevel.Function, "get", Route = "samples")] HttpRequest req, - ILogger log) - { - var content = new List() - { - new SampleResponseModel(), - }; - var result = new OkObjectResult(content); - - return await Task.FromResult(result).ConfigureAwait(false); - } - } -} diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi.CLI/Aliencube.AzureFunctions.Extensions.OpenApi.CLI.csproj b/src/Aliencube.AzureFunctions.Extensions.OpenApi.CLI/Aliencube.AzureFunctions.Extensions.OpenApi.CLI.csproj index c44c9c0..3aae421 100644 --- a/src/Aliencube.AzureFunctions.Extensions.OpenApi.CLI/Aliencube.AzureFunctions.Extensions.OpenApi.CLI.csproj +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.CLI/Aliencube.AzureFunctions.Extensions.OpenApi.CLI.csproj @@ -28,7 +28,7 @@ - + diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi.CLI/Program.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.CLI/Program.cs index cf51bb8..95c65be 100644 --- a/src/Aliencube.AzureFunctions.Extensions.OpenApi.CLI/Program.cs +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.CLI/Program.cs @@ -1,24 +1,29 @@ -using System; +using System; using System.IO; +using System.Linq; #if NET461 using System.Net.Http; #endif -using System.Reflection; using System.Text; -using Aliencube.AzureFunctions.Extensions.OpenApi.Configurations; -using Aliencube.AzureFunctions.Extensions.OpenApi.Enums; -using Aliencube.AzureFunctions.Extensions.OpenApi.Extensions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Configurations; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors; using Cocona; #if !NET461 using Microsoft.AspNetCore.Http; -#endif using Moq; +#endif + +using Newtonsoft.Json.Serialization; namespace Aliencube.AzureFunctions.Extensions.OpenApi.CLI { @@ -65,19 +70,22 @@ public void Generate( { return; } - - var assembly = Assembly.LoadFrom(pi.CompiledDllPath); #if NET461 - var req = new HttpRequestMessage(); - req.RequestUri = new Uri("http://localhost:7071"); + var requestUri = new Uri("http://localhost:7071"); + var req = new HttpRequestMessage() + { + RequestUri = requestUri, + }; #else var req = new Mock(); req.SetupGet(p => p.Scheme).Returns("http"); req.SetupGet(p => p.Host).Returns(new HostString("localhost", 7071)); #endif - var filter = new RouteConstraintFilter(); - var helper = new DocumentHelper(filter); + var acceptor = new OpenApiSchemaAcceptor(); + var namingStrategy = new CamelCaseNamingStrategy(); + var collection = this.GetVisitorCollection(); + var helper = new DocumentHelper(filter, acceptor); var document = new Document(helper); var swagger = default(string); @@ -90,7 +98,9 @@ public void Generate( #else .AddServer(req.Object, pi.HostJsonHttpSettings.RoutePrefix) #endif - .Build(assembly) + .AddNamingStrategy(namingStrategy) + .AddVisitors(collection) + .Build(pi.CompiledDllPath) .RenderAsync(version.ToOpenApiSpecVersion(), format.ToOpenApiFormat()) .Result; } @@ -126,5 +136,17 @@ public void Generate( File.WriteAllText($"{outputpath}{directorySeparator}swagger.{format.ToDisplayName()}", swagger, Encoding.UTF8); } + + private VisitorCollection GetVisitorCollection() + { + var visitors = typeof(IVisitor).Assembly + .GetTypes() + .Where(p => p.Name.EndsWith("Visitor") && p.IsClass && !p.IsAbstract) + .Select(p => (IVisitor)Activator.CreateInstance(p)) + .ToList(); + var collection = new VisitorCollection(visitors); + + return collection; + } } } diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi.CLI/ProjectInfo.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.CLI/ProjectInfo.cs index c7ba376..5ec83e3 100644 --- a/src/Aliencube.AzureFunctions.Extensions.OpenApi.CLI/ProjectInfo.cs +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.CLI/ProjectInfo.cs @@ -1,11 +1,11 @@ -using System; +using System; using System.IO; using System.Linq; using System.Text; using Aliencube.AzureFunctions.Extensions.Configuration.AppSettings.Extensions; -using Aliencube.AzureFunctions.Extensions.OpenApi.Configurations; -using Aliencube.AzureFunctions.Extensions.OpenApi.Extensions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Configurations; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; using Microsoft.Extensions.Configuration; using Microsoft.OpenApi.Models; diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Aliencube.AzureFunctions.Extensions.OpenApi.Core.csproj b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Aliencube.AzureFunctions.Extensions.OpenApi.Core.csproj new file mode 100644 index 0000000..5862522 --- /dev/null +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Aliencube.AzureFunctions.Extensions.OpenApi.Core.csproj @@ -0,0 +1,76 @@ + + + + net461;netstandard2.0 + true + true + $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb + true + Aliencube.AzureFunctions.Extensions.OpenApi.Core + Aliencube + Justin Yoo + Aliencube Community + 1.0.0 + Aliencube.AzureFunctions.Extensions.OpenApi.Core + Aliencube.AzureFunctions.Extensions.OpenApi.Core + This package helps render Open API document and Swagger UI through Azure Functions endpoints. + This package helps render Open API document and Swagger UI through Azure Functions endpoints. + Azure-Functions, Open-API, Swagger, Swagger-UI + Aliencube Community + https://github.com/aliencube/AzureFunctions.Extensions/blob/master/LICENSE + https://github.com/aliencube/AzureFunctions.Extensions + https://raw.githubusercontent.com/aliencube/AzureFunctions.Extensions/master/icons/Aliencube.AzureFunctions.Extensions.OpenApi.png + https://github.com/aliencube/AzureFunctions.Extensions + git + + + + bin\Debug\net461\Aliencube.AzureFunctions.Extensions.OpenApi.Core.xml + bin\Debug\netstandard2.0\Aliencube.AzureFunctions.Extensions.OpenApi.Core.xml + + + + bin\Release\net461\Aliencube.AzureFunctions.Extensions.OpenApi.Core.xml + bin\Release\netstandard2.0\Aliencube.AzureFunctions.Extensions.OpenApi.Core.xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Attributes/DisplayAttribute.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Attributes/DisplayAttribute.cs similarity index 89% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/Attributes/DisplayAttribute.cs rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Attributes/DisplayAttribute.cs index 9c1064f..1283aa0 100644 --- a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Attributes/DisplayAttribute.cs +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Attributes/DisplayAttribute.cs @@ -1,6 +1,6 @@ -using System; +using System; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Attributes +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes { /// /// This represents the attribute entity for enums. diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Attributes/OpenApiIgnoreAttribute.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Attributes/OpenApiIgnoreAttribute.cs similarity index 77% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/Attributes/OpenApiIgnoreAttribute.cs rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Attributes/OpenApiIgnoreAttribute.cs index be4677d..61dd358 100644 --- a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Attributes/OpenApiIgnoreAttribute.cs +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Attributes/OpenApiIgnoreAttribute.cs @@ -1,6 +1,6 @@ -using System; +using System; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Attributes +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes { /// /// This represents the attribute entity for HTTP triggers to be excluded for rendering. diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Attributes/OpenApiOperationAttribute.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Attributes/OpenApiOperationAttribute.cs similarity index 91% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/Attributes/OpenApiOperationAttribute.cs rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Attributes/OpenApiOperationAttribute.cs index 6e99afe..9c39afc 100644 --- a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Attributes/OpenApiOperationAttribute.cs +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Attributes/OpenApiOperationAttribute.cs @@ -1,8 +1,8 @@ -using System; +using System; -using Aliencube.AzureFunctions.Extensions.OpenApi.Enums; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Attributes +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes { /// /// This represents the attribute entity for HTTP triggers to define Open API operation. @@ -46,4 +46,4 @@ public OpenApiOperationAttribute(string operationId = null, params string[] tags /// public virtual OpenApiVisibilityType Visibility { get; set; } = OpenApiVisibilityType.Undefined; } -} \ No newline at end of file +} diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Attributes/OpenApiParameterAttribute.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Attributes/OpenApiParameterAttribute.cs similarity index 95% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/Attributes/OpenApiParameterAttribute.cs rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Attributes/OpenApiParameterAttribute.cs index c2c59d7..8cc3d23 100644 --- a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Attributes/OpenApiParameterAttribute.cs +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Attributes/OpenApiParameterAttribute.cs @@ -1,10 +1,10 @@ using System; -using Aliencube.AzureFunctions.Extensions.OpenApi.Enums; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums; using Microsoft.OpenApi.Models; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Attributes +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes { /// /// This represents the attribute entity for HTTP triggers to define Open API parameter. diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Attributes/OpenApiPayloadAttribute.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Attributes/OpenApiPayloadAttribute.cs similarity index 93% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/Attributes/OpenApiPayloadAttribute.cs rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Attributes/OpenApiPayloadAttribute.cs index 019785a..b8cd020 100644 --- a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Attributes/OpenApiPayloadAttribute.cs +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Attributes/OpenApiPayloadAttribute.cs @@ -1,6 +1,6 @@ -using System; +using System; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Attributes +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes { /// /// This represents the attribute entity for HTTP triggers to define payload. This MUST be inherited. diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Attributes/OpenApiRequestBodyAttribute.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Attributes/OpenApiRequestBodyAttribute.cs similarity index 92% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/Attributes/OpenApiRequestBodyAttribute.cs rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Attributes/OpenApiRequestBodyAttribute.cs index 00b2e62..15dfa4e 100644 --- a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Attributes/OpenApiRequestBodyAttribute.cs +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Attributes/OpenApiRequestBodyAttribute.cs @@ -1,6 +1,6 @@ using System; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Attributes +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes { /// /// This represents the attribute entity for HTTP triggers to define request body payload. diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Attributes/OpenApiResponseBodyAttribute.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Attributes/OpenApiResponseBodyAttribute.cs similarity index 94% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/Attributes/OpenApiResponseBodyAttribute.cs rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Attributes/OpenApiResponseBodyAttribute.cs index 8ead785..bd147d6 100644 --- a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Attributes/OpenApiResponseBodyAttribute.cs +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Attributes/OpenApiResponseBodyAttribute.cs @@ -1,7 +1,7 @@ using System; using System.Net; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Attributes +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes { /// /// This represents the attribute entity for HTTP triggers to define response body payload. diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Attributes/OpenApiResponseWithBodyAttribute.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Attributes/OpenApiResponseWithBodyAttribute.cs similarity index 93% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/Attributes/OpenApiResponseWithBodyAttribute.cs rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Attributes/OpenApiResponseWithBodyAttribute.cs index feca764..dd40f77 100644 --- a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Attributes/OpenApiResponseWithBodyAttribute.cs +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Attributes/OpenApiResponseWithBodyAttribute.cs @@ -1,7 +1,7 @@ -using System; +using System; using System.Net; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Attributes +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes { /// /// This represents the attribute entity for HTTP triggers to define response body payload. diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Attributes/OpenApiResponseWithoutBodyAttribute.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Attributes/OpenApiResponseWithoutBodyAttribute.cs similarity index 94% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/Attributes/OpenApiResponseWithoutBodyAttribute.cs rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Attributes/OpenApiResponseWithoutBodyAttribute.cs index ea97fe3..ee5e7b2 100644 --- a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Attributes/OpenApiResponseWithoutBodyAttribute.cs +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Attributes/OpenApiResponseWithoutBodyAttribute.cs @@ -1,7 +1,7 @@ using System; using System.Net; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Attributes +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes { /// /// This represents the attribute entity for HTTP triggers to define response body payload. diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Attributes/OpenApiSchemaVisibilityAttribute.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Attributes/OpenApiSchemaVisibilityAttribute.cs similarity index 87% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/Attributes/OpenApiSchemaVisibilityAttribute.cs rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Attributes/OpenApiSchemaVisibilityAttribute.cs index fca17ea..8fdfd9d 100644 --- a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Attributes/OpenApiSchemaVisibilityAttribute.cs +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Attributes/OpenApiSchemaVisibilityAttribute.cs @@ -1,8 +1,8 @@ -using System; +using System; -using Aliencube.AzureFunctions.Extensions.OpenApi.Enums; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Attributes +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes { /// /// This represents the attribute entity for Open API schema visibility. diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Configurations/ExtensionsSettings.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Configurations/ExtensionsSettings.cs similarity index 82% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/Configurations/ExtensionsSettings.cs rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Configurations/ExtensionsSettings.cs index a6fb59e..1769e21 100644 --- a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Configurations/ExtensionsSettings.cs +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Configurations/ExtensionsSettings.cs @@ -1,4 +1,4 @@ -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Configurations +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Configurations { /// /// This represents the settings entity for extensions in "host.json". @@ -10,4 +10,4 @@ public class ExtensionsSettings /// public virtual HttpSettings Http { get; set; } = new HttpSettings(); } -} \ No newline at end of file +} diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Configurations/HostJsonSettings.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Configurations/HostJsonSettings.cs similarity index 88% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/Configurations/HostJsonSettings.cs rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Configurations/HostJsonSettings.cs index da073ac..5fd0ca5 100644 --- a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Configurations/HostJsonSettings.cs +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Configurations/HostJsonSettings.cs @@ -1,6 +1,6 @@ -using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Models; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Configurations +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Configurations { /// /// This represents the settings entity for "host.json". @@ -27,4 +27,4 @@ public class HostJsonSettings /// public virtual OpenApiSettings OpenApi { get; set; } } -} \ No newline at end of file +} diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Configurations/HttpSettings.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Configurations/HttpSettings.cs similarity index 81% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/Configurations/HttpSettings.cs rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Configurations/HttpSettings.cs index e125c46..f72093e 100644 --- a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Configurations/HttpSettings.cs +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Configurations/HttpSettings.cs @@ -1,4 +1,4 @@ -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Configurations +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Configurations { /// /// This represents the settings entity for HTTP in "host.json". @@ -10,4 +10,4 @@ public class HttpSettings /// public virtual string RoutePrefix { get; set; } = "api"; } -} \ No newline at end of file +} diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Configurations/OpenApiAppSettingsBase.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Configurations/OpenApiAppSettingsBase.cs similarity index 91% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/Configurations/OpenApiAppSettingsBase.cs rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Configurations/OpenApiAppSettingsBase.cs index d97e13b..9b14316 100644 --- a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Configurations/OpenApiAppSettingsBase.cs +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Configurations/OpenApiAppSettingsBase.cs @@ -1,11 +1,11 @@ - + using Aliencube.AzureFunctions.Extensions.Configuration.AppSettings; -using Aliencube.AzureFunctions.Extensions.OpenApi.Resolvers; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Resolvers; using Microsoft.Extensions.Configuration; using Microsoft.OpenApi.Models; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Configurations +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Configurations { /// /// This represents the base settings entity from the configurations for Open API. @@ -43,4 +43,4 @@ protected OpenApiAppSettingsBase() /// public virtual HttpSettings HttpSettings { get; } } -} \ No newline at end of file +} diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Configurations/OpenApiSettings.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Configurations/OpenApiSettings.cs similarity index 74% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/Configurations/OpenApiSettings.cs rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Configurations/OpenApiSettings.cs index 324407d..c62085a 100644 --- a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Configurations/OpenApiSettings.cs +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Configurations/OpenApiSettings.cs @@ -1,6 +1,6 @@ -using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Models; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Configurations +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Configurations { /// /// This represents the settings entity for Open API metadata. @@ -12,4 +12,4 @@ public class OpenApiSettings /// public virtual OpenApiInfo Info { get; set; } } -} \ No newline at end of file +} diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Configurations/RouteConstraintFilter.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Configurations/RouteConstraintFilter.cs similarity index 88% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/Configurations/RouteConstraintFilter.cs rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Configurations/RouteConstraintFilter.cs index 4965eb4..80b814f 100644 --- a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Configurations/RouteConstraintFilter.cs +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Configurations/RouteConstraintFilter.cs @@ -1,6 +1,6 @@ -using System.Text.RegularExpressions; +using System.Text.RegularExpressions; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Configurations +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Configurations { /// /// This represents the entity for route constraint filter. @@ -30,4 +30,4 @@ public RouteConstraintFilter() /// public virtual Regex Filter { get; } } -} \ No newline at end of file +} diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Document.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Document.cs similarity index 76% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/Document.cs rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Document.cs index 130c3a1..aa3f83d 100644 --- a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Document.cs +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Document.cs @@ -7,8 +7,9 @@ using System.Reflection; using System.Threading.Tasks; -using Aliencube.AzureFunctions.Extensions.OpenApi.Abstractions; -using Aliencube.AzureFunctions.Extensions.OpenApi.Extensions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors; #if NETSTANDARD2_0 using Microsoft.AspNetCore.Http; @@ -19,7 +20,7 @@ using Newtonsoft.Json.Serialization; -namespace Aliencube.AzureFunctions.Extensions.OpenApi +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core { /// /// This represents the document entity handling Open API document. @@ -29,6 +30,8 @@ public class Document : IDocument private readonly IDocumentHelper _helper; private OpenApiDocument _document; + private NamingStrategy _strategy; + private VisitorCollection _collection; /// /// Initializes a new instance of the class. @@ -80,11 +83,35 @@ public IDocument AddServer(HttpRequest req, string routePrefix) } #endif /// - public IDocument Build(Assembly assembly, NamingStrategy namingStrategy = null) + public IDocument AddNamingStrategy(NamingStrategy strategy) { - if (namingStrategy.IsNullOrDefault()) + this._strategy = strategy.ThrowIfNullOrDefault(); + + return this; + } + + /// + public IDocument AddVisitors(VisitorCollection collection) + { + this._collection = collection.ThrowIfNullOrDefault(); + + return this; + } + + /// + public IDocument Build(string assemblyPath) + { + var assembly = Assembly.LoadFrom(assemblyPath); + + return this.Build(assembly); + } + + /// + public IDocument Build(Assembly assembly) + { + if (this._strategy.IsNullOrDefault()) { - namingStrategy = new DefaultNamingStrategy(); + this._strategy = new DefaultNamingStrategy(); } var paths = new OpenApiPaths(); @@ -121,9 +148,9 @@ public IDocument Build(Assembly assembly, NamingStrategy namingStrategy = null) continue; } - operation.Parameters = this._helper.GetOpenApiParameters(method, trigger, namingStrategy); - operation.RequestBody = this._helper.GetOpenApiRequestBody(method, namingStrategy); - operation.Responses = this._helper.GetOpenApiResponses(method, namingStrategy); + operation.Parameters = this._helper.GetOpenApiParameters(method, trigger, this._strategy, this._collection); + operation.RequestBody = this._helper.GetOpenApiRequestBody(method, this._strategy, this._collection); + operation.Responses = this._helper.GetOpenApiResponses(method, this._strategy, this._collection); operations[verb] = operation; item.Operations = operations; @@ -132,7 +159,7 @@ public IDocument Build(Assembly assembly, NamingStrategy namingStrategy = null) } this._document.Paths = paths; - this._document.Components.Schemas = this._helper.GetOpenApiSchemas(methods, namingStrategy); + this._document.Components.Schemas = this._helper.GetOpenApiSchemas(methods, this._strategy, this._collection); this._document.Components.SecuritySchemes = this._helper.GetOpenApiSecuritySchemes(); return this; diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/DocumentHelper.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/DocumentHelper.cs similarity index 78% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/DocumentHelper.cs rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/DocumentHelper.cs index 762b5f8..183447d 100644 --- a/src/Aliencube.AzureFunctions.Extensions.OpenApi/DocumentHelper.cs +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/DocumentHelper.cs @@ -3,11 +3,12 @@ using System.Linq; using System.Reflection; -using Aliencube.AzureFunctions.Extensions.OpenApi.Abstractions; -using Aliencube.AzureFunctions.Extensions.OpenApi.Attributes; -using Aliencube.AzureFunctions.Extensions.OpenApi.Configurations; -using Aliencube.AzureFunctions.Extensions.OpenApi.Enums; -using Aliencube.AzureFunctions.Extensions.OpenApi.Extensions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Configurations; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors; using Microsoft.Azure.WebJobs; using Microsoft.Azure.WebJobs.Extensions.Http; @@ -17,7 +18,7 @@ using Newtonsoft.Json.Linq; using Newtonsoft.Json.Serialization; -namespace Aliencube.AzureFunctions.Extensions.OpenApi +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core { /// /// This represents the helper entity for the class. @@ -25,14 +26,17 @@ namespace Aliencube.AzureFunctions.Extensions.OpenApi public class DocumentHelper : IDocumentHelper { private readonly RouteConstraintFilter _filter; + private readonly IOpenApiSchemaAcceptor _acceptor; /// /// Initializes a new instance of the class. /// /// instance. - public DocumentHelper(RouteConstraintFilter filter) + /// instance. + public DocumentHelper(RouteConstraintFilter filter, IOpenApiSchemaAcceptor acceptor) { this._filter = filter.ThrowIfNullOrDefault(); + this._acceptor = acceptor.ThrowIfNullOrDefault(); } /// @@ -119,12 +123,13 @@ public OpenApiOperation GetOpenApiOperation(MethodInfo element, FunctionNameAttr } /// - public List GetOpenApiParameters(MethodInfo element, HttpTriggerAttribute trigger, NamingStrategy namingStrategy = null) + public List GetOpenApiParameters(MethodInfo element, HttpTriggerAttribute trigger, NamingStrategy namingStrategy, VisitorCollection collection) { var parameters = element.GetCustomAttributes(inherit: false) - .Select(p => p.ToOpenApiParameter(namingStrategy)) + .Select(p => p.ToOpenApiParameter(namingStrategy, collection)) .ToList(); + // TODO: Should this be forcibly provided? // This needs to be provided separately. if (trigger.AuthLevel != AuthorizationLevel.Anonymous) { @@ -135,7 +140,7 @@ public List GetOpenApiParameters(MethodInfo element, HttpTrigg } /// - public OpenApiRequestBody GetOpenApiRequestBody(MethodInfo element, NamingStrategy namingStrategy = null) + public OpenApiRequestBody GetOpenApiRequestBody(MethodInfo element, NamingStrategy namingStrategy, VisitorCollection collection) { var attributes = element.GetCustomAttributes(inherit: false); if (!attributes.Any()) @@ -143,7 +148,7 @@ public OpenApiRequestBody GetOpenApiRequestBody(MethodInfo element, NamingStrate return null; } - var contents = attributes.ToDictionary(p => p.ContentType, p => p.ToOpenApiMediaType(namingStrategy)); + var contents = attributes.ToDictionary(p => p.ContentType, p => p.ToOpenApiMediaType(namingStrategy, collection)); if (contents.Any()) { @@ -161,7 +166,7 @@ public OpenApiRequestBody GetOpenApiRequestBody(MethodInfo element, NamingStrate [Obsolete("This method is obsolete from 2.0.0. Use GetOpenApiResponses instead", error: true)] public OpenApiResponses GetOpenApiResponseBody(MethodInfo element, NamingStrategy namingStrategy = null) { - return this.GetOpenApiResponses(element, namingStrategy); + return this.GetOpenApiResponses(element, namingStrategy, null); //var responses = element.GetCustomAttributes(inherit: false) // .ToDictionary(p => ((int)p.StatusCode).ToString(), p => p.ToOpenApiResponse(namingStrategy)) @@ -171,7 +176,7 @@ public OpenApiResponses GetOpenApiResponseBody(MethodInfo element, NamingStrateg } /// - public OpenApiResponses GetOpenApiResponses(MethodInfo element, NamingStrategy namingStrategy = null) + public OpenApiResponses GetOpenApiResponses(MethodInfo element, NamingStrategy namingStrategy, VisitorCollection collection) { var responsesWithBody = element.GetCustomAttributes(inherit: false) .Select(p => new { StatusCode = p.StatusCode, Response = p.ToOpenApiResponse(namingStrategy) }); @@ -187,7 +192,7 @@ public OpenApiResponses GetOpenApiResponses(MethodInfo element, NamingStrategy n } /// - public Dictionary GetOpenApiSchemas(List elements, NamingStrategy namingStrategy) + public Dictionary GetOpenApiSchemas(List elements, NamingStrategy namingStrategy, VisitorCollection collection) { var requests = elements.SelectMany(p => p.GetCustomAttributes(inherit: false)) .Select(p => p.BodyType); @@ -202,10 +207,30 @@ public Dictionary GetOpenApiSchemas(List elem .Where(p => !typeof(Array).IsAssignableFrom(p)) .ToList(); + var rootSchemas = new Dictionary(); var schemas = new Dictionary(); - types.ForEach(p => schemas.AddRange(p.ToOpenApiSchemas(namingStrategy))); - return schemas; + this._acceptor.Types = types.ToDictionary(p => p.GetOpenApiTypeName(namingStrategy), p => p); + this._acceptor.RootSchemas = rootSchemas; + this._acceptor.Schemas = schemas; + + this._acceptor.Accept(collection, namingStrategy); + //types.ForEach(p => schemas.AddRange(p.ToOpenApiSchemas(namingStrategy))); + + var union = schemas.Union(rootSchemas) + .Distinct() + .OrderBy(p => p.Key) + .ToDictionary(p => p.Key, + p => + { + // Title was intentionally added for schema key. + // It's not necessary when it's added to the root schema. + // Therefore, it's removed. + p.Value.Title = null; + return p.Value; + }); + + return union; } /// diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Enums/OpenApiFormatType.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Enums/OpenApiFormatType.cs similarity index 74% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/Enums/OpenApiFormatType.cs rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Enums/OpenApiFormatType.cs index 54e5c2a..7fbde87 100644 --- a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Enums/OpenApiFormatType.cs +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Enums/OpenApiFormatType.cs @@ -1,6 +1,6 @@ -using Aliencube.AzureFunctions.Extensions.OpenApi.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Enums +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums { /// /// This specifies the Open API format. diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Enums/OpenApiParameterCollectionDelimiterType.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Enums/OpenApiParameterCollectionDelimiterType.cs similarity index 80% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/Enums/OpenApiParameterCollectionDelimiterType.cs rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Enums/OpenApiParameterCollectionDelimiterType.cs index 7418313..d96c8c4 100644 --- a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Enums/OpenApiParameterCollectionDelimiterType.cs +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Enums/OpenApiParameterCollectionDelimiterType.cs @@ -1,6 +1,6 @@ -using Aliencube.AzureFunctions.Extensions.OpenApi.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Enums +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums { /// /// This specifies the parameter collection delimiter. diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Enums/OpenApiVersionType.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Enums/OpenApiVersionType.cs similarity index 75% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/Enums/OpenApiVersionType.cs rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Enums/OpenApiVersionType.cs index 475a0c2..b3e33e4 100644 --- a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Enums/OpenApiVersionType.cs +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Enums/OpenApiVersionType.cs @@ -1,6 +1,6 @@ -using Aliencube.AzureFunctions.Extensions.OpenApi.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Enums +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums { /// /// This specifies the version of Open API. diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Enums/OpenApiVisibilityType.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Enums/OpenApiVisibilityType.cs similarity index 86% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/Enums/OpenApiVisibilityType.cs rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Enums/OpenApiVisibilityType.cs index 6043415..b4b4ca2 100644 --- a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Enums/OpenApiVisibilityType.cs +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Enums/OpenApiVisibilityType.cs @@ -1,6 +1,6 @@ -using Aliencube.AzureFunctions.Extensions.OpenApi.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Enums +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums { /// /// This specifies the visibility of an attribute, which is used for Logic Apps and/or PowerApps. diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/EnumExtensions.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/EnumExtensions.cs similarity index 91% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/EnumExtensions.cs rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/EnumExtensions.cs index a1e1d10..13f2a3f 100644 --- a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/EnumExtensions.cs +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/EnumExtensions.cs @@ -2,12 +2,14 @@ using System.Linq; using System.Reflection; -using Aliencube.AzureFunctions.Extensions.OpenApi.Attributes; -using Aliencube.AzureFunctions.Extensions.OpenApi.Enums; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums; using Microsoft.OpenApi; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Extensions +using Newtonsoft.Json.Serialization; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions { /// /// This represents the extension entity for enums. @@ -18,15 +20,21 @@ public static class EnumExtensions /// Gets the display name of the enum value. /// /// Enum value. + /// instance. /// Display name of the enum value. - public static string ToDisplayName(this Enum @enum) + public static string ToDisplayName(this Enum @enum, NamingStrategy namingStrategy = null) { + if (namingStrategy.IsNullOrDefault()) + { + namingStrategy = new DefaultNamingStrategy(); + } + var type = @enum.GetType(); var member = type.GetMember(@enum.ToString()).First(); var attribute = member.GetCustomAttribute(inherit: false); var name = attribute == null ? @enum.ToString() : attribute.Name; - return name; + return namingStrategy.GetPropertyName(name, hasSpecifiedName: false); } /// diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/GenericExtensions.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/GenericExtensions.cs similarity index 97% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/GenericExtensions.cs rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/GenericExtensions.cs index 7c59314..46efb58 100644 --- a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/GenericExtensions.cs +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/GenericExtensions.cs @@ -1,8 +1,8 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Extensions +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions { /// /// This represents the extension entity for generic. diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/MemberInfoExtensions.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/MemberInfoExtensions.cs similarity index 91% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/MemberInfoExtensions.cs rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/MemberInfoExtensions.cs index a3b2c39..9130c20 100644 --- a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/MemberInfoExtensions.cs +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/MemberInfoExtensions.cs @@ -1,7 +1,7 @@ -using System; +using System; using System.Reflection; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Extensions +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions { /// /// This represents the extension entity for . @@ -24,4 +24,4 @@ public static bool ExistsCustomAttribute(this MemberInfo element, bool inheri return exists; } } -} \ No newline at end of file +} diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/MethodInfoExtensions.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/MethodInfoExtensions.cs similarity index 92% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/MethodInfoExtensions.cs rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/MethodInfoExtensions.cs index 3d990d6..1de1f3a 100644 --- a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/MethodInfoExtensions.cs +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/MethodInfoExtensions.cs @@ -1,11 +1,11 @@ -using System.Linq; +using System.Linq; using System.Reflection; -using Aliencube.AzureFunctions.Extensions.OpenApi.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; using Microsoft.Azure.WebJobs; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Extensions +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions { /// /// This represents the extension entity for . @@ -56,4 +56,4 @@ public static OpenApiOperationAttribute GetOpenApiOperation(this MethodInfo elem return operation; } } -} \ No newline at end of file +} diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/OpenApiDocumentExtensions.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/OpenApiDocumentExtensions.cs similarity index 94% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/OpenApiDocumentExtensions.cs rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/OpenApiDocumentExtensions.cs index a0b295e..85f75ce 100644 --- a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/OpenApiDocumentExtensions.cs +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/OpenApiDocumentExtensions.cs @@ -1,10 +1,10 @@ -using System; +using System; using System.IO; using Microsoft.OpenApi; using Microsoft.OpenApi.Models; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Extensions +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions { /// /// This represents the extension entity for . @@ -41,4 +41,4 @@ public static void Serialise(this OpenApiDocument document, TextWriter writer, O } } } -} \ No newline at end of file +} diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/OpenApiInfoExtensions.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/OpenApiInfoExtensions.cs similarity index 88% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/OpenApiInfoExtensions.cs rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/OpenApiInfoExtensions.cs index 1ba1e2f..bb7681b 100644 --- a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/OpenApiInfoExtensions.cs +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/OpenApiInfoExtensions.cs @@ -1,6 +1,6 @@ -using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Models; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Extensions +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions { /// /// This represents the extension entity for . @@ -19,4 +19,4 @@ public static bool IsValid(this OpenApiInfo openApiInfo) return !openApiInfo.IsNullOrDefault() && !openApiInfo.Version.IsNullOrDefault() && !openApiInfo.Title.IsNullOrWhiteSpace(); } } -} \ No newline at end of file +} diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/OpenApiParameterAttributeExtensions.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/OpenApiParameterAttributeExtensions.cs similarity index 63% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/OpenApiParameterAttributeExtensions.cs rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/OpenApiParameterAttributeExtensions.cs index 8ca65da..b90e859 100644 --- a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/OpenApiParameterAttributeExtensions.cs +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/OpenApiParameterAttributeExtensions.cs @@ -1,17 +1,13 @@ -using System.Linq; -using System.Reflection; - -using Aliencube.AzureFunctions.Extensions.OpenApi.Attributes; -using Aliencube.AzureFunctions.Extensions.OpenApi.Enums; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors; using Microsoft.OpenApi.Any; using Microsoft.OpenApi.Models; -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; using Newtonsoft.Json.Serialization; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Extensions +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions { /// /// This represents the extension entity for . @@ -22,48 +18,26 @@ public static class OpenApiParameterAttributeExtensions /// Converts to . /// /// instance. - /// + /// instance. + /// instance. /// instance. - public static OpenApiParameter ToOpenApiParameter(this OpenApiParameterAttribute attribute, NamingStrategy namingStrategy = null) + public static OpenApiParameter ToOpenApiParameter(this OpenApiParameterAttribute attribute, NamingStrategy namingStrategy = null, VisitorCollection collection = null) { attribute.ThrowIfNullOrDefault(); - var type = attribute.Type; - - var schema = new OpenApiSchema() - { - Type = type.ToDataType(), - Format = type.ToDataFormat(), - }; - - if (type.IsOpenApiArray()) + if (namingStrategy.IsNullOrDefault()) { - schema.Type = "array"; - schema.Format = null; - schema.Items = (type.GetElementType() ?? type.GetGenericArguments()[0]).ToOpenApiSchema(namingStrategy); + namingStrategy = new DefaultNamingStrategy(); } - if (type.IsUnflaggedEnumType()) + if (collection.IsNullOrDefault()) { - var converterAttribute = type.GetCustomAttribute(); - if (!converterAttribute.IsNullOrDefault() - && typeof(StringEnumConverter).IsAssignableFrom(converterAttribute.ConverterType)) - { - var enums = type.ToOpenApiStringCollection(namingStrategy); + collection = VisitorCollection.CreateInstance(); + } - schema.Type = "string"; - schema.Format = null; - schema.Enum = enums; - schema.Default = enums.First(); - } - else - { - var enums = type.ToOpenApiIntegerCollection(); + var type = attribute.Type; - schema.Enum = enums; - schema.Default = enums.First(); - } - } + var schema = collection.ParameterVisit(type, namingStrategy); var parameter = new OpenApiParameter() { diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/OpenApiParameterExtensions.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/OpenApiParameterExtensions.cs similarity index 82% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/OpenApiParameterExtensions.cs rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/OpenApiParameterExtensions.cs index 75f2d82..2ac02f0 100644 --- a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/OpenApiParameterExtensions.cs +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/OpenApiParameterExtensions.cs @@ -1,9 +1,9 @@ -using System; +using System; using System.Collections.Generic; using Microsoft.OpenApi.Models; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Extensions +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions { /// /// This represents the extension entity for . @@ -53,21 +53,21 @@ public static List AddOpenApiParameter( name.ThrowIfNullOrWhiteSpace(); var schema = new OpenApiSchema() - { - Type = type.ToDataType(), - Format = type.ToDataFormat() - }; + { + Type = type.ToDataType(), + Format = type.ToDataFormat() + }; var parameter = new OpenApiParameter() - { - Name = name, - Description = description, - Required = required, - In = @in, - Schema = schema - }; + { + Name = name, + Description = description, + Required = required, + In = @in, + Schema = schema + }; parameters.Add(parameter); return parameters; } } -} \ No newline at end of file +} diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/OpenApiPayloadAttributeExtensions.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/OpenApiPayloadAttributeExtensions.cs new file mode 100644 index 0000000..1efe304 --- /dev/null +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/OpenApiPayloadAttributeExtensions.cs @@ -0,0 +1,59 @@ +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors; + +using Microsoft.OpenApi.Models; + +using Newtonsoft.Json.Serialization; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions +{ + /// + /// This represents the extension entity for . + /// + public static class OpenApiPayloadAttributeExtensions + { + /// + /// Converts to . + /// + /// Type of payload attribute inheriting . + /// OpenApi payload attribute. + /// instance to create the JSON schema from .NET Types. + /// instance. + /// instance. + public static OpenApiMediaType ToOpenApiMediaType(this T attribute, NamingStrategy namingStrategy = null, VisitorCollection collection = null) where T : OpenApiPayloadAttribute + { + attribute.ThrowIfNullOrDefault(); + + if (namingStrategy.IsNullOrDefault()) + { + namingStrategy = new DefaultNamingStrategy(); + } + + if (collection.IsNullOrDefault()) + { + collection = VisitorCollection.CreateInstance(); + } + + var type = attribute.BodyType; + + // Generate schema based on the type. + var schema = collection.PayloadVisit(type, namingStrategy); + + // For array and dictionary object, the reference has already been added by the visitor. + if (!type.IsOpenApiArray() && !type.IsOpenApiDictionary()) + { + var reference = new OpenApiReference() + { + Type = ReferenceType.Schema, + Id = attribute.BodyType.GetOpenApiReferenceId(isDictionary: false, isList: false, namingStrategy) + }; + + schema.Reference = reference; + } + + var mediaType = new OpenApiMediaType() { Schema = schema }; + + return mediaType; + } + } +} diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/OpenApiResponseWithBodyAttributeExtensions.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/OpenApiResponseWithBodyAttributeExtensions.cs similarity index 82% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/OpenApiResponseWithBodyAttributeExtensions.cs rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/OpenApiResponseWithBodyAttributeExtensions.cs index ebb6fa4..6cd0533 100644 --- a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/OpenApiResponseWithBodyAttributeExtensions.cs +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/OpenApiResponseWithBodyAttributeExtensions.cs @@ -1,13 +1,14 @@ using System.Collections.Generic; -using Aliencube.AzureFunctions.Extensions.OpenApi.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors; using Microsoft.OpenApi.Any; using Microsoft.OpenApi.Models; using Newtonsoft.Json.Serialization; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Extensions +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions { /// /// This represents the extension entity for . @@ -19,15 +20,16 @@ public static class OpenApiResponseWithBodyAttributeExtensions /// /// instance. /// instance to create the JSON schema from .NET Types. + /// instance. /// instance. - public static OpenApiResponse ToOpenApiResponse(this OpenApiResponseWithBodyAttribute attribute, NamingStrategy namingStrategy = null) + public static OpenApiResponse ToOpenApiResponse(this OpenApiResponseWithBodyAttribute attribute, NamingStrategy namingStrategy = null, VisitorCollection collection = null) { attribute.ThrowIfNullOrDefault(); var description = string.IsNullOrWhiteSpace(attribute.Description) ? $"Payload of {attribute.BodyType.GetOpenApiDescription()}" : attribute.Description; - var mediaType = attribute.ToOpenApiMediaType(namingStrategy); + var mediaType = attribute.ToOpenApiMediaType(namingStrategy, collection); var content = new Dictionary() { { attribute.ContentType, mediaType } diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/OpenApiResponseWithoutBodyAttributeExtensions.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/OpenApiResponseWithoutBodyAttributeExtensions.cs similarity index 91% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/OpenApiResponseWithoutBodyAttributeExtensions.cs rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/OpenApiResponseWithoutBodyAttributeExtensions.cs index 60bdf19..44c724d 100644 --- a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/OpenApiResponseWithoutBodyAttributeExtensions.cs +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/OpenApiResponseWithoutBodyAttributeExtensions.cs @@ -1,11 +1,11 @@ -using Aliencube.AzureFunctions.Extensions.OpenApi.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; using Microsoft.OpenApi.Any; using Microsoft.OpenApi.Models; using Newtonsoft.Json.Serialization; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Extensions +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions { /// /// This represents the extension entity for . diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/OpenApiResponsesExtensions.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/OpenApiResponsesExtensions.cs similarity index 93% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/OpenApiResponsesExtensions.cs rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/OpenApiResponsesExtensions.cs index 302ec8f..898d9a5 100644 --- a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/OpenApiResponsesExtensions.cs +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/OpenApiResponsesExtensions.cs @@ -2,7 +2,7 @@ using Microsoft.OpenApi.Models; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Extensions +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions { /// /// This represents the extension entity for . diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/OpenApiSchemaExtensions.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/OpenApiSchemaExtensions.cs similarity index 96% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/OpenApiSchemaExtensions.cs rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/OpenApiSchemaExtensions.cs index d451b6c..e1e26ea 100644 --- a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/OpenApiSchemaExtensions.cs +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/OpenApiSchemaExtensions.cs @@ -3,7 +3,7 @@ using System.Linq; using System.Reflection; -using Aliencube.AzureFunctions.Extensions.OpenApi.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; using Microsoft.OpenApi.Any; using Microsoft.OpenApi.Models; @@ -12,11 +12,12 @@ using Newtonsoft.Json.Converters; using Newtonsoft.Json.Serialization; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Extensions +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions { /// /// This represents the extension entity for . /// + [Obsolete("This extension class is now obsolete", error: true)] public static class OpenApiSchemaExtensions { /// @@ -29,6 +30,7 @@ public static class OpenApiSchemaExtensions /// /// It runs recursively to build the entire object type. It only takes properties without . /// + [Obsolete("This method is now obsolete", error: true)] public static OpenApiSchema ToOpenApiSchema(this Type type, NamingStrategy namingStrategy, OpenApiSchemaVisibilityAttribute attribute = null) { return ToOpenApiSchemas(type, namingStrategy, attribute, true).Single().Value; @@ -43,12 +45,13 @@ public static OpenApiSchema ToOpenApiSchema(this Type type, NamingStrategy namin /// Value indicating whether to return single schema or not. /// Recurring depth. /// Returns instance. + [Obsolete("This method is now obsolete", error: true)] public static Dictionary ToOpenApiSchemas(this Type type, NamingStrategy namingStrategy, OpenApiSchemaVisibilityAttribute attribute = null, bool returnSingleSchema = false, int depth = 0) { type.ThrowIfNullOrDefault(); var schema = (OpenApiSchema)null; - var schemeName = type.IsGenericType ? type.GetOpenApiGenericRootName() : type.Name; + var schemeName = type.GetOpenApiTypeName(namingStrategy); if (depth == 8) { @@ -70,8 +73,7 @@ public static Dictionary ToOpenApiSchemas(this Type type, return new Dictionary() { { schemeName, schema } }; } - var unwrappedValueType = Nullable.GetUnderlyingType(type); - if (!unwrappedValueType.IsNullOrDefault()) + if (type.IsOpenApiNullable(out var unwrappedValueType)) { schema = unwrappedValueType.ToOpenApiSchemas(namingStrategy, null, true, depth).Single().Value; schema.Nullable = true; @@ -143,7 +145,7 @@ public static Dictionary ToOpenApiSchemas(this Type type, foreach (var property in properties) { var visiblity = property.GetCustomAttribute(inherit: false); - var propertyName = property.GetJsonPropertyName(); + var propertyName = property.GetJsonPropertyName(namingStrategy); var ts = property.DeclaringType.GetGenericArguments(); if (!ts.Any()) diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/ParameterInfoExtensions.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/ParameterInfoExtensions.cs similarity index 91% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/ParameterInfoExtensions.cs rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/ParameterInfoExtensions.cs index bcffa18..28a680a 100644 --- a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/ParameterInfoExtensions.cs +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/ParameterInfoExtensions.cs @@ -1,7 +1,7 @@ -using System; +using System; using System.Reflection; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Extensions +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions { /// /// This represents the extension entity for . @@ -24,4 +24,4 @@ public static bool ExistsCustomAttribute(this ParameterInfo element, bool inh return exists; } } -} \ No newline at end of file +} diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/PropertyInfoExtensions.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/PropertyInfoExtensions.cs new file mode 100644 index 0000000..1e7629e --- /dev/null +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/PropertyInfoExtensions.cs @@ -0,0 +1,49 @@ +using System.Reflection; + +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions +{ + /// + /// This represents the extension entity for class. + /// + public static class PropertyInfoExtensions + { + /// + /// Checks whether the given object has or not. + /// + /// instance. + /// Returns True, if the given object has ; otherwise, returns False. + public static bool HasJsonPropertyAttribute(this PropertyInfo element) + { + var exists = element.ExistsCustomAttribute(); + + return exists; + } + + /// + /// Gets the name from instance. + /// + /// instance. + /// instance. + /// Returns the name from instance. + public static string GetJsonPropertyName(this PropertyInfo element, NamingStrategy namingStrategy = null) + { + if (namingStrategy.IsNullOrDefault()) + { + namingStrategy = new DefaultNamingStrategy(); + } + + if (element.HasJsonPropertyAttribute()) + { + var name = element.GetCustomAttribute().PropertyName; + + return name; + + } + + return namingStrategy.GetPropertyName(element.Name, hasSpecifiedName: false); + } + } +} diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/StringExtensions.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/StringExtensions.cs similarity index 94% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/StringExtensions.cs rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/StringExtensions.cs index 0231087..a058cc2 100644 --- a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/StringExtensions.cs +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/StringExtensions.cs @@ -1,6 +1,6 @@ -using System; +using System; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Extensions +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions { /// /// This represents the extension class for . diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/SwaggerUIExtensions.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/SwaggerUIExtensions.cs similarity index 84% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/SwaggerUIExtensions.cs rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/SwaggerUIExtensions.cs index b3a9b26..2c0b8e4 100644 --- a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/SwaggerUIExtensions.cs +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/SwaggerUIExtensions.cs @@ -1,8 +1,8 @@ -using System.Threading.Tasks; +using System.Threading.Tasks; -using Aliencube.AzureFunctions.Extensions.OpenApi.Abstractions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Extensions +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions { /// /// This represents the extension entity for . @@ -24,4 +24,4 @@ public static async Task RenderAsync(this Task ui, string en return await instance.RenderAsync(endpoint, authKey).ConfigureAwait(false); } } -} \ No newline at end of file +} diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/TypeExtensions.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/TypeExtensions.cs similarity index 62% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/TypeExtensions.cs rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/TypeExtensions.cs index 1842e6a..7380241 100644 --- a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/TypeExtensions.cs +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Extensions/TypeExtensions.cs @@ -1,13 +1,15 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Reflection; using Microsoft.OpenApi.Any; +using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Newtonsoft.Json.Serialization; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Extensions +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions { /// /// This represents the extension entity for . @@ -132,6 +134,60 @@ public static List ToOpenApiStringCollection(this Type type, Naming .ToList(); } + /// + /// Converts the given instance to the list of underlying enum values of . + /// + /// instance. + /// Returns the list of underlying enum values of . + public static List ToOpenApiInt16Collection(this Type type) + { + if (!type.IsUnflaggedEnumType()) + { + return null; + } + + var names = Enum.GetValues(type).Cast(); + + return names.Select(p => (IOpenApiAny)new OpenApiInteger(Convert.ToInt32(p))) + .ToList(); + } + + /// + /// Converts the given instance to the list of underlying enum values of . + /// + /// instance. + /// Returns the list of underlying enum values of . + public static List ToOpenApiInt32Collection(this Type type) + { + if (!type.IsUnflaggedEnumType()) + { + return null; + } + + var names = Enum.GetValues(type).Cast(); + + return names.Select(p => (IOpenApiAny)new OpenApiInteger(p)) + .ToList(); + } + + /// + /// Converts the given instance to the list of underlying enum values of . + /// + /// instance. + /// Returns the list of underlying enum values of . + public static List ToOpenApiInt64Collection(this Type type) + { + if (!type.IsUnflaggedEnumType()) + { + return null; + } + + var names = Enum.GetValues(type).Cast(); + + return names.Select(p => (IOpenApiAny)new OpenApiLong(p)) + .ToList(); + } + /// /// Converts the given instance to the list of underlying enum value. /// @@ -199,21 +255,74 @@ public static bool IsOpenApiDictionary(this Type type) return type.IsDictionaryType(); } + /// + /// Checks whether the given type is nullable or not. + /// + /// Type to check. + /// Returns True, if the given type is nullable; otherwise returns False. + public static bool IsOpenApiNullable(this Type type) + { + return type.IsNullableType(out var underlyingType); + } + + /// + /// Checks whether the given type is nullable or not. + /// + /// Type to check. + /// Underlying type to return + /// Returns True, if the given type is nullable; otherwise returns False. + public static bool IsOpenApiNullable(this Type type, out Type underlyingType) + { + if (type.IsNullOrDefault()) + { + underlyingType = null; + + return false; + } + + return type.IsNullableType(out underlyingType); + } + + /// + /// Checks whether the given enum type has or not. + /// + /// Type of . + /// Enum type. + /// Returns True, if the given enum type has ; otherwise, returns False. + public static bool HasJsonConverterAttribute(this Type type) where T : JsonConverter + { + var attribute = type.GetCustomAttribute(inherit: false); + if (attribute.IsNullOrDefault()) + { + return false; + } + + return typeof(T).IsAssignableFrom(attribute.ConverterType); + } + /// /// Gets the Open API reference ID. /// /// instance. /// Value indicating whether the type is or not. /// Value indicating whether the type is or not. + /// instance. /// Returns the Open API reference ID. - public static string GetOpenApiReferenceId(this Type type, bool isDictionary, bool isList) + public static string GetOpenApiReferenceId(this Type type, bool isDictionary, bool isList, NamingStrategy namingStrategy = null) { + if (namingStrategy.IsNullOrDefault()) + { + namingStrategy = new DefaultNamingStrategy(); + } + if (isDictionary || isList) { - return type.GetOpenApiSubTypeName(); + var name = type.GetOpenApiSubTypeName(namingStrategy); + + return namingStrategy.GetPropertyName(name, hasSpecifiedName: false); } - return type.Name; + return namingStrategy.GetPropertyName(type.Name, hasSpecifiedName: false); } /// @@ -284,6 +393,25 @@ public static string GetOpenApiGenericRootName(this Type type) return name; } + /// + /// Gets the type name applied by . + /// + /// Type to check. + /// instance. + /// Returns the type name applied by . + public static string GetOpenApiTypeName(this Type type, NamingStrategy namingStrategy = null) + { + if (namingStrategy.IsNullOrDefault()) + { + namingStrategy = new DefaultNamingStrategy(); + } + + var typeName = type.IsGenericType ? type.GetOpenApiGenericRootName() : type.Name; + var name = namingStrategy.GetPropertyName(typeName, hasSpecifiedName: false); + + return name; + } + /// /// Gets the sub type of the given . @@ -314,22 +442,34 @@ public static Type GetOpenApiSubType(this Type type) /// Gets the name of the sub type of the given . /// /// instance. + /// instance. /// Returns the name of the sub type of the given . - public static string GetOpenApiSubTypeName(this Type type) + public static string GetOpenApiSubTypeName(this Type type, NamingStrategy namingStrategy = null) { + if (namingStrategy.IsNullOrDefault()) + { + namingStrategy = new DefaultNamingStrategy(); + } + if (type.IsDictionaryType()) { - return type.GetGenericArguments()[1].Name; + var name = type.GetGenericArguments()[1].Name; + + return namingStrategy.GetPropertyName(name, hasSpecifiedName: false); } if (type.BaseType == typeof(Array)) { - return type.GetElementType().Name; + var name = type.GetElementType().Name; + + return namingStrategy.GetPropertyName(name, hasSpecifiedName: false); } if (type.IsArrayType()) { - return type.GetGenericArguments()[0].Name; + var name = type.GetGenericArguments()[0].Name; + + return namingStrategy.GetPropertyName(name, hasSpecifiedName: false); } return null; @@ -363,6 +503,22 @@ public static string GetOpenApiSubTypeNames(this Type type) return names; } + /// + /// Checks whether the given type has a recursive property or not. + /// + /// Type to check. + /// Returns True, if the given type has a recursive property; otherwise returns False. + public static bool HasRecursiveProperty(this Type type) + { + var properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance) + .Where(p => !p.ExistsCustomAttribute()); + + var hasRecursiveType = properties.Select(p => p.PropertyType) + .Any(p => p == type); + + return hasRecursiveType; + } + private static bool IsArrayType(this Type type) { if (type.BaseType == typeof(Array)) @@ -380,11 +536,26 @@ private static bool IsArrayType(this Type type) return true; } + if (type.IsGenericTypeOf(typeof(ICollection<>))) + { + return true; + } + if (type.IsGenericTypeOf(typeof(IEnumerable<>))) { return true; } + if (type.IsGenericTypeOf(typeof(IReadOnlyList<>))) + { + return true; + } + + if (type.IsGenericTypeOf(typeof(IReadOnlyCollection<>))) + { + return true; + } + return false; } @@ -405,7 +576,24 @@ private static bool IsDictionaryType(this Type type) return true; } + if (type.Name.Equals("IReadOnlyDictionary`2", StringComparison.CurrentCultureIgnoreCase)) + { + return true; + } + + if (type.Name.Equals("KeyValuePair`2", StringComparison.CurrentCultureIgnoreCase)) + { + return true; + } + return false; } + + private static bool IsNullableType(this Type type, out Type underlyingType) + { + underlyingType = Nullable.GetUnderlyingType(type); + + return !underlyingType.IsNullOrDefault(); + } } } diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/IDocument.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/IDocument.cs similarity index 67% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/IDocument.cs rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/IDocument.cs index c04394b..df40320 100644 --- a/src/Aliencube.AzureFunctions.Extensions.OpenApi/IDocument.cs +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/IDocument.cs @@ -1,10 +1,12 @@ -#if NET461 +#if NET461 using System.Net.Http; #endif using System.Reflection; using System.Threading.Tasks; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors; + #if NETSTANDARD2_0 using Microsoft.AspNetCore.Http; #endif @@ -14,7 +16,7 @@ using Newtonsoft.Json.Serialization; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Abstractions +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions { /// /// This provides interfaces to the class. @@ -51,13 +53,33 @@ public interface IDocument /// instance. IDocument AddServer(HttpRequest req, string routePrefix); #endif + /// + /// Adds the naming strategy. + /// + /// instance to create the JSON schema from .NET Types. + /// instance. + IDocument AddNamingStrategy(NamingStrategy strategy); + + /// + /// Adds the visitor collection. + /// + /// instance. + /// instance. + IDocument AddVisitors(VisitorCollection collection); + + /// + /// Builds Open API document. + /// + /// Assembly file path. + /// instance. + IDocument Build(string assemblyPath); + /// /// Builds Open API document. /// /// instance. - /// instance to create the JSON schema from .NET Types. /// instance. - IDocument Build(Assembly assembly, NamingStrategy namingStrategy = null); + IDocument Build(Assembly assembly); /// /// Renders Open API document. @@ -67,4 +89,4 @@ public interface IDocument /// Serialised Open API document. Task RenderAsync(OpenApiSpecVersion version, OpenApiFormat format); } -} \ No newline at end of file +} diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/IDocumentHelper.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/IDocumentHelper.cs similarity index 87% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/IDocumentHelper.cs rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/IDocumentHelper.cs index c3788f7..e6e8720 100644 --- a/src/Aliencube.AzureFunctions.Extensions.OpenApi/IDocumentHelper.cs +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/IDocumentHelper.cs @@ -2,12 +2,14 @@ using System.Collections.Generic; using System.Reflection; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors; + using Microsoft.Azure.WebJobs; using Microsoft.OpenApi.Models; using Newtonsoft.Json.Serialization; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Abstractions +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions { /// /// This provides interfaces to the class. @@ -73,16 +75,18 @@ public interface IDocumentHelper /// instance. /// instance. /// instance to create the JSON schema from .NET Types. + /// instance to process parameters. /// List of instance. - List GetOpenApiParameters(MethodInfo element, HttpTriggerAttribute trigger, NamingStrategy namingStrategy = null); + List GetOpenApiParameters(MethodInfo element, HttpTriggerAttribute trigger, NamingStrategy namingStrategy, VisitorCollection collection); /// /// Gets the instance. /// /// instance. /// instance to create the JSON schema from .NET Types. + /// instance to process parameters. /// instance. - OpenApiRequestBody GetOpenApiRequestBody(MethodInfo element, NamingStrategy namingStrategy = null); + OpenApiRequestBody GetOpenApiRequestBody(MethodInfo element, NamingStrategy namingStrategy, VisitorCollection collection); /// /// Gets the instance. @@ -98,16 +102,18 @@ public interface IDocumentHelper /// /// instance. /// instance to create the JSON schema from .NET Types. + /// instance to process parameters. /// instance. - OpenApiResponses GetOpenApiResponses(MethodInfo element, NamingStrategy namingStrategy = null); + OpenApiResponses GetOpenApiResponses(MethodInfo element, NamingStrategy namingStrategy, VisitorCollection collection); /// /// Gets the collection of instances. /// /// List of instance. /// instance to create the JSON schema from .NET Types. + /// instance to add types to schema. /// Collection of instance. - Dictionary GetOpenApiSchemas(List elements, NamingStrategy namingStrategy); + Dictionary GetOpenApiSchemas(List elements, NamingStrategy namingStrategy, VisitorCollection collection); /// /// Gets the collection of instances. diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/ISwaggerUI.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/ISwaggerUI.cs similarity index 94% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/ISwaggerUI.cs rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/ISwaggerUI.cs index 5847621..dd3d6bc 100644 --- a/src/Aliencube.AzureFunctions.Extensions.OpenApi/ISwaggerUI.cs +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/ISwaggerUI.cs @@ -1,8 +1,7 @@ -#if NET461 +#if NET461 using System.Net.Http; #endif -using System.Reflection; using System.Threading.Tasks; #if NETSTANDARD2_0 @@ -11,7 +10,7 @@ using Microsoft.OpenApi.Models; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Abstractions +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions { /// /// This provides interfaces to the class. diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/OpenApiWriterFactory.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/OpenApiWriterFactory.cs similarity index 93% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/OpenApiWriterFactory.cs rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/OpenApiWriterFactory.cs index dd3d650..156e25a 100644 --- a/src/Aliencube.AzureFunctions.Extensions.OpenApi/OpenApiWriterFactory.cs +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/OpenApiWriterFactory.cs @@ -1,10 +1,10 @@ -using System; +using System; using System.IO; using Microsoft.OpenApi; using Microsoft.OpenApi.Writers; -namespace Aliencube.AzureFunctions.Extensions.OpenApi +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core { /// /// This represents the factory entity to create a write instance based on the Open API document format. @@ -32,4 +32,4 @@ public static IOpenApiWriter CreateInstance(OpenApiFormat format, TextWriter wri } } } -} \ No newline at end of file +} diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Resolvers/HostJsonResolver.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Resolvers/HostJsonResolver.cs similarity index 90% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/Resolvers/HostJsonResolver.cs rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Resolvers/HostJsonResolver.cs index 708accc..b22e08b 100644 --- a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Resolvers/HostJsonResolver.cs +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Resolvers/HostJsonResolver.cs @@ -1,13 +1,13 @@ -using System; +using System; using Aliencube.AzureFunctions.Extensions.Configuration.AppSettings.Extensions; using Aliencube.AzureFunctions.Extensions.Configuration.AppSettings.Resolvers; -using Aliencube.AzureFunctions.Extensions.OpenApi.Configurations; -using Aliencube.AzureFunctions.Extensions.OpenApi.Extensions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Configurations; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; using Microsoft.Extensions.Configuration; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Resolvers +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Resolvers { /// /// This represents the resolver entity for host.json. diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Resolvers/OpenApiInfoResolver.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Resolvers/OpenApiInfoResolver.cs similarity index 93% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/Resolvers/OpenApiInfoResolver.cs rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Resolvers/OpenApiInfoResolver.cs index 5f150cc..65717e8 100644 --- a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Resolvers/OpenApiInfoResolver.cs +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Resolvers/OpenApiInfoResolver.cs @@ -1,13 +1,13 @@ -using System; +using System; using Aliencube.AzureFunctions.Extensions.Configuration.AppSettings.Extensions; using Aliencube.AzureFunctions.Extensions.Configuration.AppSettings.Resolvers; -using Aliencube.AzureFunctions.Extensions.OpenApi.Extensions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; using Microsoft.Extensions.Configuration; using Microsoft.OpenApi.Models; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Resolvers +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Resolvers { /// /// This represents the resolver entity for from one of host.json, openapisettings.json and environment variables. diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Resolvers/OpenApiSettingsJsonResolver.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Resolvers/OpenApiSettingsJsonResolver.cs similarity index 90% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/Resolvers/OpenApiSettingsJsonResolver.cs rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Resolvers/OpenApiSettingsJsonResolver.cs index 3a6d512..e2f8544 100644 --- a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Resolvers/OpenApiSettingsJsonResolver.cs +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Resolvers/OpenApiSettingsJsonResolver.cs @@ -1,11 +1,11 @@ -using System.IO; +using System.IO; using Aliencube.AzureFunctions.Extensions.Configuration.AppSettings.Resolvers; -using Aliencube.AzureFunctions.Extensions.OpenApi.Extensions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; using Microsoft.Extensions.Configuration; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Resolvers +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Resolvers { /// /// This represents the resolver entity for openapisettings.json. diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/SwaggerUI.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/SwaggerUI.cs similarity index 95% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/SwaggerUI.cs rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/SwaggerUI.cs index 6ee501e..c7c1b30 100644 --- a/src/Aliencube.AzureFunctions.Extensions.OpenApi/SwaggerUI.cs +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/SwaggerUI.cs @@ -1,4 +1,4 @@ -using System.IO; +using System.IO; #if NET461 using System.Net.Http; @@ -7,8 +7,8 @@ using System.Reflection; using System.Threading.Tasks; -using Aliencube.AzureFunctions.Extensions.OpenApi.Abstractions; -using Aliencube.AzureFunctions.Extensions.OpenApi.Extensions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; #if NETSTANDARD2_0 using Microsoft.AspNetCore.Http; @@ -16,7 +16,7 @@ using Microsoft.OpenApi.Models; -namespace Aliencube.AzureFunctions.Extensions.OpenApi +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core { /// /// This represents the entity to render UI for Open API. diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/BooleanTypeVisitor.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/BooleanTypeVisitor.cs new file mode 100644 index 0000000..ab4ad4f --- /dev/null +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/BooleanTypeVisitor.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; + +using Microsoft.OpenApi.Models; + +using Newtonsoft.Json.Serialization; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors +{ + /// + /// This represents the type visitor for . + /// + public class BooleanTypeVisitor : TypeVisitor + { + /// + public override bool IsVisitable(Type type) + { + var isVisitable = this.IsVisitable(type, TypeCode.Boolean); + + return isVisitable; + } + + /// + public override void Visit(IAcceptor acceptor, KeyValuePair type, NamingStrategy namingStrategy, params Attribute[] attributes) + { + this.Visit(acceptor, name: type.Key, title: null, dataType: "boolean", dataFormat: null, attributes: attributes); + } + + /// + public override bool IsParameterVisitable(Type type) + { + var isVisitable = this.IsVisitable(type); + + return isVisitable; + } + + /// + public override OpenApiSchema ParameterVisit(Type type, NamingStrategy namingStrategy) + { + return this.ParameterVisit(dataType: "boolean", dataFormat: null); + } + + /// + public override bool IsPayloadVisitable(Type type) + { + var isVisitable = this.IsVisitable(type); + + return isVisitable; + } + + /// + public override OpenApiSchema PayloadVisit(Type type, NamingStrategy namingStrategy) + { + return this.PayloadVisit(dataType: "boolean", dataFormat: null); + } + } +} diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/DateTimeObjectTypeVisitor.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/DateTimeObjectTypeVisitor.cs new file mode 100644 index 0000000..c61a378 --- /dev/null +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/DateTimeObjectTypeVisitor.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; + +using Microsoft.OpenApi.Models; + +using Newtonsoft.Json.Serialization; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors +{ + /// + /// This represents the type visitor for . + /// + public class DateTimeObjectTypeVisitor : TypeVisitor + { + /// + public override bool IsVisitable(Type type) + { + var isVisitable = this.IsVisitable(type, TypeCode.Object) && type == typeof(DateTime); + + return isVisitable; + } + + /// + public override void Visit(IAcceptor acceptor, KeyValuePair type, NamingStrategy namingStrategy, params Attribute[] attributes) + { + this.Visit(acceptor, name: type.Key, title: null, dataType: "string", dataFormat: "date-time", attributes: attributes); + } + + /// + public override bool IsParameterVisitable(Type type) + { + var isVisitable = this.IsVisitable(type); + + return isVisitable; + } + + /// + public override OpenApiSchema ParameterVisit(Type type, NamingStrategy namingStrategy) + { + return this.ParameterVisit(dataType: "string", dataFormat: "date-time"); + } + + /// + public override bool IsPayloadVisitable(Type type) + { + var isVisitable = this.IsVisitable(type); + + return isVisitable; + } + + /// + public override OpenApiSchema PayloadVisit(Type type, NamingStrategy namingStrategy) + { + return this.PayloadVisit(dataType: "string", dataFormat: "date-time"); + } + } +} diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/DateTimeOffsetObjectTypeVisitor.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/DateTimeOffsetObjectTypeVisitor.cs new file mode 100644 index 0000000..196640b --- /dev/null +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/DateTimeOffsetObjectTypeVisitor.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; + +using Microsoft.OpenApi.Models; + +using Newtonsoft.Json.Serialization; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors +{ + /// + /// This represents the type visitor for . + /// + public class DateTimeOffsetObjectTypeVisitor : TypeVisitor + { + /// + public override bool IsVisitable(Type type) + { + var isVisitable = this.IsVisitable(type, TypeCode.Object) && type == typeof(DateTimeOffset); + + return isVisitable; + } + + /// + public override void Visit(IAcceptor acceptor, KeyValuePair type, NamingStrategy namingStrategy, params Attribute[] attributes) + { + this.Visit(acceptor, name: type.Key, title: null, dataType: "string", dataFormat: "date-time", attributes: attributes); + } + + /// + public override bool IsParameterVisitable(Type type) + { + var isVisitable = this.IsVisitable(type); + + return isVisitable; + } + + /// + public override OpenApiSchema ParameterVisit(Type type, NamingStrategy namingStrategy) + { + return this.ParameterVisit(dataType: "string", dataFormat: "date-time"); + } + + /// + public override bool IsPayloadVisitable(Type type) + { + var isVisitable = this.IsVisitable(type); + + return isVisitable; + } + + /// + public override OpenApiSchema PayloadVisit(Type type, NamingStrategy namingStrategy) + { + return this.PayloadVisit(dataType: "string", dataFormat: "date-time"); + } + } +} diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/DateTimeTypeVisitor.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/DateTimeTypeVisitor.cs new file mode 100644 index 0000000..c7e18a5 --- /dev/null +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/DateTimeTypeVisitor.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; + +using Microsoft.OpenApi.Models; + +using Newtonsoft.Json.Serialization; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors +{ + /// + /// This represents the type visitor for . + /// + public class DateTimeTypeVisitor : TypeVisitor + { + /// + public override bool IsVisitable(Type type) + { + var isVisitable = this.IsVisitable(type, TypeCode.DateTime); + + return isVisitable; + } + + /// + public override void Visit(IAcceptor acceptor, KeyValuePair type, NamingStrategy namingStrategy, params Attribute[] attributes) + { + this.Visit(acceptor, name: type.Key, title: null, dataType: "string", dataFormat: "date-time", attributes: attributes); + } + + /// + public override bool IsParameterVisitable(Type type) + { + var isVisitable = this.IsVisitable(type); + + return isVisitable; + } + + /// + public override OpenApiSchema ParameterVisit(Type type, NamingStrategy namingStrategy) + { + return this.ParameterVisit(dataType: "string", dataFormat: "date-time"); + } + + /// + public override bool IsPayloadVisitable(Type type) + { + var isVisitable = this.IsVisitable(type); + + return isVisitable; + } + + /// + public override OpenApiSchema PayloadVisit(Type type, NamingStrategy namingStrategy) + { + return this.PayloadVisit(dataType: "string", dataFormat: "date-time"); + } + } +} diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/DecimalTypeVisitor.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/DecimalTypeVisitor.cs new file mode 100644 index 0000000..951dec4 --- /dev/null +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/DecimalTypeVisitor.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; + +using Microsoft.OpenApi.Models; + +using Newtonsoft.Json.Serialization; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors +{ + /// + /// This represents the type visitor for . + /// + public class DecimalTypeVisitor : TypeVisitor + { + /// + public override bool IsVisitable(Type type) + { + var isVisitable = this.IsVisitable(type, TypeCode.Decimal); + + return isVisitable; + } + + /// + public override void Visit(IAcceptor acceptor, KeyValuePair type, NamingStrategy namingStrategy, params Attribute[] attributes) + { + this.Visit(acceptor, name: type.Key, title: null, dataType: "number", dataFormat: "double", attributes: attributes); + } + + /// + public override bool IsParameterVisitable(Type type) + { + var isVisitable = this.IsVisitable(type); + + return isVisitable; + } + + /// + public override OpenApiSchema ParameterVisit(Type type, NamingStrategy namingStrategy) + { + return this.ParameterVisit(dataType: "number", dataFormat: "double"); + } + + /// + public override bool IsPayloadVisitable(Type type) + { + var isVisitable = this.IsVisitable(type); + + return isVisitable; + } + + /// + public override OpenApiSchema PayloadVisit(Type type, NamingStrategy namingStrategy) + { + return this.PayloadVisit(dataType: "number", dataFormat: "double"); + } + } +} diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/DictionaryObjectTypeVisitor.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/DictionaryObjectTypeVisitor.cs new file mode 100644 index 0000000..7ee542a --- /dev/null +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/DictionaryObjectTypeVisitor.cs @@ -0,0 +1,140 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; + +using Microsoft.OpenApi.Models; + +using Newtonsoft.Json.Serialization; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors +{ + /// + /// This represents the type visitor for . + /// + public class DictionaryObjectTypeVisitor : TypeVisitor + { + /// + public override bool IsVisitable(Type type) + { + var isVisitable = this.IsVisitable(type, TypeCode.Object) && type.IsOpenApiDictionary(); + + return isVisitable; + } + + /// + public override void Visit(IAcceptor acceptor, KeyValuePair type, NamingStrategy namingStrategy, params Attribute[] attributes) + { + var name = this.Visit(acceptor, name: type.Key, title: null, dataType: "object", dataFormat: null, attributes: attributes); + + if (name.IsNullOrWhiteSpace()) + { + return; + } + + var instance = acceptor as OpenApiSchemaAcceptor; + if (instance.IsNullOrDefault()) + { + return; + } + + // Gets the schema for the underlying type. + var underlyingType = type.Value.GetGenericArguments()[1]; + var types = new Dictionary() + { + { underlyingType.GetOpenApiTypeName(namingStrategy), underlyingType } + }; + var schemas = new Dictionary(); + + var subAcceptor = new OpenApiSchemaAcceptor() + { + Types = types, + RootSchemas = instance.RootSchemas, + Schemas = schemas, + }; + + var collection = VisitorCollection.CreateInstance(); + subAcceptor.Accept(collection, namingStrategy); + + var properties = subAcceptor.Schemas.First().Value; + + // Adds the reference to the schema for the underlying type. + if (this.IsReferential(underlyingType)) + { + var reference = new OpenApiReference() + { + Type = ReferenceType.Schema, + Id = underlyingType.GetOpenApiReferenceId(isDictionary: false, isList: false, namingStrategy) + }; + + properties.Reference = reference; + } + + instance.Schemas[name].AdditionalProperties = properties; + + // Adds schemas to the root. + var schemasToBeAdded = subAcceptor.Schemas + .Where(p => !instance.Schemas.Keys.Contains(p.Key)) + .Where(p => p.Value.Type == "object" && + p.Value.Format.IsNullOrWhiteSpace() && + p.Value.Items.IsNullOrDefault() && + p.Value.AdditionalProperties.IsNullOrDefault()) + .ToDictionary(p => p.Key, p => p.Value); + + if (!schemasToBeAdded.Any()) + { + return; + } + + foreach (var schemaToBeAdded in schemasToBeAdded) + { + if (instance.RootSchemas.ContainsKey(schemaToBeAdded.Key)) + { + continue; + } + + instance.RootSchemas.Add(schemaToBeAdded.Key, schemaToBeAdded.Value); + } + } + + /// + public override bool IsParameterVisitable(Type type) + { + return false; + } + + /// + public override bool IsPayloadVisitable(Type type) + { + var isVisitable = this.IsVisitable(type); + + return isVisitable; + } + + /// + public override OpenApiSchema PayloadVisit(Type type, NamingStrategy namingStrategy) + { + var schema = this.PayloadVisit(dataType: "object", dataFormat: null); + + // Gets the schema for the underlying type. + var underlyingType = type.GetGenericArguments()[1]; + var collection = VisitorCollection.CreateInstance(); + var properties = collection.PayloadVisit(underlyingType, namingStrategy); + + // Adds the reference to the schema for the underlying type. + var reference = new OpenApiReference() + { + Type = ReferenceType.Schema, + Id = underlyingType.GetOpenApiReferenceId(isDictionary: false, isList: false, namingStrategy) + }; + + properties.Reference = reference; + + schema.AdditionalProperties = properties; + + return schema; + } + } +} diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/DoubleTypeVisitor.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/DoubleTypeVisitor.cs new file mode 100644 index 0000000..d3aa779 --- /dev/null +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/DoubleTypeVisitor.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; + +using Microsoft.OpenApi.Models; + +using Newtonsoft.Json.Serialization; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors +{ + /// + /// This represents the type visitor for . + /// + public class DoubleTypeVisitor : TypeVisitor + { + /// + public override bool IsVisitable(Type type) + { + var isVisitable = this.IsVisitable(type, TypeCode.Double); + + return isVisitable; + } + + /// + public override void Visit(IAcceptor acceptor, KeyValuePair type, NamingStrategy namingStrategy, params Attribute[] attributes) + { + this.Visit(acceptor, name: type.Key, title: null, dataType: "number", dataFormat: "double", attributes: attributes); + } + + /// + public override bool IsParameterVisitable(Type type) + { + var isVisitable = this.IsVisitable(type); + + return isVisitable; + } + + /// + public override OpenApiSchema ParameterVisit(Type type, NamingStrategy namingStrategy) + { + return this.ParameterVisit(dataType: "number", dataFormat: "double"); + } + + /// + public override bool IsPayloadVisitable(Type type) + { + var isVisitable = this.IsVisitable(type); + + return isVisitable; + } + + /// + public override OpenApiSchema PayloadVisit(Type type, NamingStrategy namingStrategy) + { + return this.PayloadVisit(dataType: "number", dataFormat: "double"); + } + } +} diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/GuidObjectTypeVisitor.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/GuidObjectTypeVisitor.cs new file mode 100644 index 0000000..27fb0ae --- /dev/null +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/GuidObjectTypeVisitor.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; + +using Microsoft.OpenApi.Models; + +using Newtonsoft.Json.Serialization; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors +{ + /// + /// This represents the type visitor for . + /// + public class GuidObjectTypeVisitor : TypeVisitor + { + /// + public override bool IsVisitable(Type type) + { + var isVisitable = this.IsVisitable(type, TypeCode.Object) && type == typeof(Guid); + + return isVisitable; + } + + /// + public override void Visit(IAcceptor acceptor, KeyValuePair type, NamingStrategy namingStrategy, params Attribute[] attributes) + { + this.Visit(acceptor, name: type.Key, title: null, dataType: "string", dataFormat: "uuid", attributes: attributes); + } + + /// + public override bool IsParameterVisitable(Type type) + { + var isVisitable = this.IsVisitable(type); + + return isVisitable; + } + + /// + public override OpenApiSchema ParameterVisit(Type type, NamingStrategy namingStrategy) + { + return this.ParameterVisit(dataType: "string", dataFormat: "uuid"); + } + + /// + public override bool IsPayloadVisitable(Type type) + { + var isVisitable = this.IsVisitable(type); + + return isVisitable; + } + + /// + public override OpenApiSchema PayloadVisit(Type type, NamingStrategy namingStrategy) + { + return this.PayloadVisit(dataType: "string", dataFormat: "uuid"); + } + } +} diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/IAcceptor.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/IAcceptor.cs new file mode 100644 index 0000000..12f7fee --- /dev/null +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/IAcceptor.cs @@ -0,0 +1,19 @@ +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors; + +using Newtonsoft.Json.Serialization; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions +{ + /// + /// This provides interfaces to the acceptor classes. + /// + public interface IAcceptor + { + /// + /// Accepts the visitors. + /// + /// instance. + /// instance. + void Accept(VisitorCollection collection, NamingStrategy namingStrategy); + } +} diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/IOpenApiSchemaAcceptor.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/IOpenApiSchemaAcceptor.cs new file mode 100644 index 0000000..8948832 --- /dev/null +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/IOpenApiSchemaAcceptor.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; + +using Microsoft.OpenApi.Models; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors +{ + /// + /// This provides interfaces to the class. + /// + public interface IOpenApiSchemaAcceptor : IAcceptor + { + /// + /// Gets the list of instances as key/value pair representing the root schemas. + /// + Dictionary RootSchemas { get; set; } + + /// + /// Gets the list of instances as key/value pair. + /// + Dictionary Schemas { get; set; } + + /// + /// Gets the list of objects. + /// + Dictionary Types { get; set; } + } +} diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/IVisitor.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/IVisitor.cs new file mode 100644 index 0000000..07f43a8 --- /dev/null +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/IVisitor.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; + +using Microsoft.OpenApi.Models; + +using Newtonsoft.Json.Serialization; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions +{ + /// + /// This provides interfaces to visitor classes. + /// + public interface IVisitor + { + /// + /// Checks whether the type is visitable or not. + /// + /// Type to check. + /// Returns True, if the type is visitable; otherwise returns False. + bool IsVisitable(Type type); + + /// + /// Visits and process the acceptor. + /// + /// instance. + /// Type to check. + /// instance. + /// List of attribute instances. + void Visit(IAcceptor acceptor, KeyValuePair type, NamingStrategy namingStrategy, params Attribute[] attributes); + + /// + /// Checks whether the type is navigatable to its sub-type or not. + /// + /// Type to check. + /// Returns True, if the type is navigatable; otherwise returns False. + bool IsNavigatable(Type type); + + /// + /// Checks whether the type is visitable or not for parameters. + /// + /// Type to check. + /// Returns True, if the type is visitable for parameters; otherwise returns False. + bool IsParameterVisitable(Type type); + + /// + /// Visits and process the type for parameters. + /// + /// Type to check. + /// instance. + OpenApiSchema ParameterVisit(Type type, NamingStrategy namingStrategy); + + /// + /// Checks whether the type is visitable or not for payloads. + /// + /// Type to check. + /// Returns True, if the type is visitable for payloads; otherwise returns False. + bool IsPayloadVisitable(Type type); + + /// + /// Visits and process the type for payloads. + /// + /// Type to check. + /// instance. + OpenApiSchema PayloadVisit(Type type, NamingStrategy namingStrategy); + } +} diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/Int16EnumTypeVisitor.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/Int16EnumTypeVisitor.cs new file mode 100644 index 0000000..26ba8ab --- /dev/null +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/Int16EnumTypeVisitor.cs @@ -0,0 +1,115 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; + +using Microsoft.OpenApi.Any; +using Microsoft.OpenApi.Models; + +using Newtonsoft.Json.Converters; +using Newtonsoft.Json.Serialization; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors +{ + /// + /// This represents the type visitor for type enum. + /// + public class Int16EnumTypeVisitor : TypeVisitor + { + /// + public override bool IsVisitable(Type type) + { + var isVisitable = this.IsVisitable(type, TypeCode.Int16) && + type.IsUnflaggedEnumType() && + !type.HasJsonConverterAttribute() && + Enum.GetUnderlyingType(type) == typeof(short) + ; + + return isVisitable; + } + + /// + public override void Visit(IAcceptor acceptor, KeyValuePair type, NamingStrategy namingStrategy, params Attribute[] attributes) + { + var name = type.Key; + + var instance = acceptor as OpenApiSchemaAcceptor; + if (instance.IsNullOrDefault()) + { + return; + } + + // Adds enum values to the schema. + var enums = type.Value.ToOpenApiInt16Collection(); + + var schema = new OpenApiSchema() + { + Type = "integer", + Format = "int32", + Enum = enums, + Default = enums.First() + }; + + // Adds the visibility property. + if (attributes.Any()) + { + var visibilityAttribute = attributes.OfType().SingleOrDefault(); + if (!visibilityAttribute.IsNullOrDefault()) + { + var extension = new OpenApiString(visibilityAttribute.Visibility.ToDisplayName()); + + schema.Extensions.Add("x-ms-visibility", extension); + } + } + + instance.Schemas.Add(name, schema); + } + + /// + public override bool IsParameterVisitable(Type type) + { + var isVisitable = this.IsVisitable(type); + + return isVisitable; + } + + /// + public override OpenApiSchema ParameterVisit(Type type, NamingStrategy namingStrategy) + { + var schema = this.ParameterVisit(dataType: "integer", dataFormat: "int32"); + + // Adds enum values to the schema. + var enums = type.ToOpenApiInt16Collection(); + + schema.Enum = enums; + schema.Default = enums.First(); + + return schema; + } + + /// + public override bool IsPayloadVisitable(Type type) + { + var isVisitable = this.IsVisitable(type); + + return isVisitable; + } + + /// + public override OpenApiSchema PayloadVisit(Type type, NamingStrategy namingStrategy) + { + var schema = this.PayloadVisit(dataType: "integer", dataFormat: "int32"); + + // Adds enum values to the schema. + var enums = type.ToOpenApiInt16Collection(); + + schema.Enum = enums; + schema.Default = enums.First(); + + return schema; + } + } +} diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/Int16TypeVisitor.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/Int16TypeVisitor.cs new file mode 100644 index 0000000..d5f5895 --- /dev/null +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/Int16TypeVisitor.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; + +using Microsoft.OpenApi.Models; + +using Newtonsoft.Json.Serialization; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors +{ + /// + /// This represents the type visitor for . + /// + public class Int16TypeVisitor : TypeVisitor + { + /// + public override bool IsVisitable(Type type) + { + var isVisitable = this.IsVisitable(type, TypeCode.Int16) && + !type.IsUnflaggedEnumType(); + + return isVisitable; + } + + /// + public override void Visit(IAcceptor acceptor, KeyValuePair type, NamingStrategy namingStrategy, params Attribute[] attributes) + { + this.Visit(acceptor, name: type.Key, title: null, dataType: "integer", dataFormat: "int32", attributes: attributes); + } + + /// + public override bool IsParameterVisitable(Type type) + { + var isVisitable = this.IsVisitable(type); + + return isVisitable; + } + + /// + public override OpenApiSchema ParameterVisit(Type type, NamingStrategy namingStrategy) + { + return this.ParameterVisit(dataType: "integer", dataFormat: "int32"); + } + + /// + public override bool IsPayloadVisitable(Type type) + { + var isVisitable = this.IsVisitable(type); + + return isVisitable; + } + + /// + public override OpenApiSchema PayloadVisit(Type type, NamingStrategy namingStrategy) + { + return this.PayloadVisit(dataType: "integer", dataFormat: "int32"); + } + } +} diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/Int32EnumTypeVisitor.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/Int32EnumTypeVisitor.cs new file mode 100644 index 0000000..93f60cf --- /dev/null +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/Int32EnumTypeVisitor.cs @@ -0,0 +1,115 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; + +using Microsoft.OpenApi.Any; +using Microsoft.OpenApi.Models; + +using Newtonsoft.Json.Converters; +using Newtonsoft.Json.Serialization; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors +{ + /// + /// This represents the type visitor for type enum. + /// + public class Int32EnumTypeVisitor : TypeVisitor + { + /// + public override bool IsVisitable(Type type) + { + var isVisitable = this.IsVisitable(type, TypeCode.Int32) && + type.IsUnflaggedEnumType() && + !type.HasJsonConverterAttribute() && + Enum.GetUnderlyingType(type) == typeof(int) + ; + + return isVisitable; + } + + /// + public override void Visit(IAcceptor acceptor, KeyValuePair type, NamingStrategy namingStrategy, params Attribute[] attributes) + { + var name = type.Key; + + var instance = acceptor as OpenApiSchemaAcceptor; + if (instance.IsNullOrDefault()) + { + return; + } + + // Adds enum values to the schema. + var enums = type.Value.ToOpenApiInt32Collection(); + + var schema = new OpenApiSchema() + { + Type = "integer", + Format = "int32", + Enum = enums, + Default = enums.First() + }; + + // Adds the visibility property. + if (attributes.Any()) + { + var visibilityAttribute = attributes.OfType().SingleOrDefault(); + if (!visibilityAttribute.IsNullOrDefault()) + { + var extension = new OpenApiString(visibilityAttribute.Visibility.ToDisplayName()); + + schema.Extensions.Add("x-ms-visibility", extension); + } + } + + instance.Schemas.Add(name, schema); + } + + /// + public override bool IsParameterVisitable(Type type) + { + var isVisitable = this.IsVisitable(type); + + return isVisitable; + } + + /// + public override OpenApiSchema ParameterVisit(Type type, NamingStrategy namingStrategy) + { + var schema = this.ParameterVisit(dataType: "integer", dataFormat: "int32"); + + // Adds enum values to the schema. + var enums = type.ToOpenApiInt32Collection(); + + schema.Enum = enums; + schema.Default = enums.First(); + + return schema; + } + + /// + public override bool IsPayloadVisitable(Type type) + { + var isVisitable = this.IsVisitable(type); + + return isVisitable; + } + + /// + public override OpenApiSchema PayloadVisit(Type type, NamingStrategy namingStrategy) + { + var schema = this.PayloadVisit(dataType: "integer", dataFormat: "int32"); + + // Adds enum values to the schema. + var enums = type.ToOpenApiInt32Collection(); + + schema.Enum = enums; + schema.Default = enums.First(); + + return schema; + } + } +} diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/Int32TypeVisitor.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/Int32TypeVisitor.cs new file mode 100644 index 0000000..59eefbb --- /dev/null +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/Int32TypeVisitor.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; + +using Microsoft.OpenApi.Models; + +using Newtonsoft.Json.Serialization; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors +{ + /// + /// This represents the type visitor for . + /// + public class Int32TypeVisitor : TypeVisitor + { + /// + public override bool IsVisitable(Type type) + { + var isVisitable = this.IsVisitable(type, TypeCode.Int32) && + !type.IsUnflaggedEnumType(); + + return isVisitable; + } + + /// + public override void Visit(IAcceptor acceptor, KeyValuePair type, NamingStrategy namingStrategy, params Attribute[] attributes) + { + this.Visit(acceptor, name: type.Key, title: null, dataType: "integer", dataFormat: "int32", attributes: attributes); + } + + /// + public override bool IsParameterVisitable(Type type) + { + var isVisitable = this.IsVisitable(type); + + return isVisitable; + } + + /// + public override OpenApiSchema ParameterVisit(Type type, NamingStrategy namingStrategy) + { + return this.ParameterVisit(dataType: "integer", dataFormat: "int32"); + } + + /// + public override bool IsPayloadVisitable(Type type) + { + var isVisitable = this.IsVisitable(type); + + return isVisitable; + } + + /// + public override OpenApiSchema PayloadVisit(Type type, NamingStrategy namingStrategy) + { + return this.PayloadVisit(dataType: "integer", dataFormat: "int32"); + } + } +} diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/Int64EnumTypeVisitor.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/Int64EnumTypeVisitor.cs new file mode 100644 index 0000000..f7b1a3a --- /dev/null +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/Int64EnumTypeVisitor.cs @@ -0,0 +1,115 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; + +using Microsoft.OpenApi.Any; +using Microsoft.OpenApi.Models; + +using Newtonsoft.Json.Converters; +using Newtonsoft.Json.Serialization; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors +{ + /// + /// This represents the type visitor for type enum. + /// + public class Int64EnumTypeVisitor : TypeVisitor + { + /// + public override bool IsVisitable(Type type) + { + var isVisitable = this.IsVisitable(type, TypeCode.Int64) && + type.IsUnflaggedEnumType() && + !type.HasJsonConverterAttribute() && + Enum.GetUnderlyingType(type) == typeof(long) + ; + + return isVisitable; + } + + /// + public override void Visit(IAcceptor acceptor, KeyValuePair type, NamingStrategy namingStrategy, params Attribute[] attributes) + { + var name = type.Key; + + var instance = acceptor as OpenApiSchemaAcceptor; + if (instance.IsNullOrDefault()) + { + return; + } + + // Adds enum values to the schema. + var enums = type.Value.ToOpenApiInt64Collection(); + + var schema = new OpenApiSchema() + { + Type = "integer", + Format = "int64", + Enum = enums, + Default = enums.First() + }; + + // Adds the visibility property. + if (attributes.Any()) + { + var visibilityAttribute = attributes.OfType().SingleOrDefault(); + if (!visibilityAttribute.IsNullOrDefault()) + { + var extension = new OpenApiString(visibilityAttribute.Visibility.ToDisplayName()); + + schema.Extensions.Add("x-ms-visibility", extension); + } + } + + instance.Schemas.Add(name, schema); + } + + /// + public override bool IsParameterVisitable(Type type) + { + var isVisitable = this.IsVisitable(type); + + return isVisitable; + } + + /// + public override OpenApiSchema ParameterVisit(Type type, NamingStrategy namingStrategy) + { + var schema = this.ParameterVisit(dataType: "integer", dataFormat: "int64"); + + // Adds enum values to the schema. + var enums = type.ToOpenApiInt64Collection(); + + schema.Enum = enums; + schema.Default = enums.First(); + + return schema; + } + + /// + public override bool IsPayloadVisitable(Type type) + { + var isVisitable = this.IsVisitable(type); + + return isVisitable; + } + + /// + public override OpenApiSchema PayloadVisit(Type type, NamingStrategy namingStrategy) + { + var schema = this.PayloadVisit(dataType: "integer", dataFormat: "int64"); + + // Adds enum values to the schema. + var enums = type.ToOpenApiInt64Collection(); + + schema.Enum = enums; + schema.Default = enums.First(); + + return schema; + } + } +} diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/Int64TypeVisitor.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/Int64TypeVisitor.cs new file mode 100644 index 0000000..864cd73 --- /dev/null +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/Int64TypeVisitor.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; + +using Microsoft.OpenApi.Models; + +using Newtonsoft.Json.Serialization; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors +{ + /// + /// This represents the type visitor for . + /// + public class Int64TypeVisitor : TypeVisitor + { + /// + public override bool IsVisitable(Type type) + { + var isVisitable = this.IsVisitable(type, TypeCode.Int64) && + !type.IsUnflaggedEnumType(); + + return isVisitable; + } + + /// + public override void Visit(IAcceptor acceptor, KeyValuePair type, NamingStrategy namingStrategy, params Attribute[] attributes) + { + this.Visit(acceptor, name: type.Key, title: null, dataType: "integer", dataFormat: "int64", attributes: attributes); + } + + /// + public override bool IsParameterVisitable(Type type) + { + var isVisitable = this.IsVisitable(type); + + return isVisitable; + } + + /// + public override OpenApiSchema ParameterVisit(Type type, NamingStrategy namingStrategy) + { + return this.ParameterVisit(dataType: "integer", dataFormat: "int64"); + } + + /// + public override bool IsPayloadVisitable(Type type) + { + var isVisitable = this.IsVisitable(type); + + return isVisitable; + } + + /// + public override OpenApiSchema PayloadVisit(Type type, NamingStrategy namingStrategy) + { + return this.PayloadVisit(dataType: "integer", dataFormat: "int64"); + } + } +} diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/JObjectTypeVisitor.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/JObjectTypeVisitor.cs new file mode 100644 index 0000000..5e03e67 --- /dev/null +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/JObjectTypeVisitor.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; + +using Microsoft.OpenApi.Models; + +using Newtonsoft.Json.Linq; +using Newtonsoft.Json.Serialization; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors +{ + /// + /// This represents the type visitor for or . + /// + public class JObjectTypeVisitor : TypeVisitor + { + /// + public override bool IsVisitable(Type type) + { + var isVisitable = this.IsVisitable(type, TypeCode.Object) && type.IsJObjectType(); + + return isVisitable; + } + + /// + public override void Visit(IAcceptor acceptor, KeyValuePair type, NamingStrategy namingStrategy, params Attribute[] attributes) + { + var title = namingStrategy.GetPropertyName(type.Value.Name, hasSpecifiedName: false); + this.Visit(acceptor, name: type.Key, title: title, dataType: "object", dataFormat: null, attributes: attributes); + } + + /// + public override bool IsParameterVisitable(Type type) + { + return false; + } + + /// + public override bool IsPayloadVisitable(Type type) + { + var isVisitable = this.IsVisitable(type); + + return isVisitable; + } + + /// + public override OpenApiSchema PayloadVisit(Type type, NamingStrategy namingStrategy) + { + return this.PayloadVisit(dataType: "object", dataFormat: null); + } + } +} diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/ListObjectTypeVisitor.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/ListObjectTypeVisitor.cs new file mode 100644 index 0000000..8b105cf --- /dev/null +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/ListObjectTypeVisitor.cs @@ -0,0 +1,156 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; + +using Microsoft.OpenApi.Models; + +using Newtonsoft.Json.Serialization; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors +{ + /// + /// This represents the type visitor for . + /// + public class ListObjectTypeVisitor : TypeVisitor + { + /// + public override bool IsVisitable(Type type) + { + var isVisitable = this.IsVisitable(type, TypeCode.Object) && type.IsOpenApiArray(); + + return isVisitable; + } + + /// + public override void Visit(IAcceptor acceptor, KeyValuePair type, NamingStrategy namingStrategy, params Attribute[] attributes) + { + var name = this.Visit(acceptor, name: type.Key, title: null, dataType: "array", dataFormat: null, attributes: attributes); + + if (name.IsNullOrWhiteSpace()) + { + return; + } + + var instance = acceptor as OpenApiSchemaAcceptor; + if (instance.IsNullOrDefault()) + { + return; + } + + // Gets the schema for the underlying type. + var underlyingType = type.Value.GetElementType() ?? type.Value.GetGenericArguments()[0]; + var types = new Dictionary() + { + { underlyingType.GetOpenApiTypeName(namingStrategy), underlyingType } + }; + var schemas = new Dictionary(); + + var subAcceptor = new OpenApiSchemaAcceptor() + { + Types = types, + RootSchemas = instance.RootSchemas, + Schemas = schemas, + }; + + var collection = VisitorCollection.CreateInstance(); + subAcceptor.Accept(collection, namingStrategy); + + var items = subAcceptor.Schemas.First().Value; + + // Adds the reference to the schema for the underlying type. + if (this.IsReferential(underlyingType)) + { + var reference = new OpenApiReference() + { + Type = ReferenceType.Schema, + Id = underlyingType.GetOpenApiReferenceId(isDictionary: false, isList: false, namingStrategy) + }; + + items.Reference = reference; + } + + instance.Schemas[name].Items = items; + + // Adds schemas to the root. + var schemasToBeAdded = subAcceptor.Schemas + .Where(p => !instance.Schemas.Keys.Contains(p.Key)) + .Where(p => p.Value.Type == "object" && + p.Value.Format.IsNullOrWhiteSpace() && + p.Value.Items.IsNullOrDefault() && + p.Value.AdditionalProperties.IsNullOrDefault()) + .ToDictionary(p => p.Key, p => p.Value); + + if (!schemasToBeAdded.Any()) + { + return; + } + + foreach (var schema in schemasToBeAdded) + { + if (instance.RootSchemas.ContainsKey(schema.Key)) + { + continue; + } + + instance.RootSchemas.Add(schema.Key, schema.Value); + } + } + + /// + public override bool IsParameterVisitable(Type type) + { + var isVisitable = this.IsVisitable(type); + + return isVisitable; + } + + /// + public override OpenApiSchema ParameterVisit(Type type, NamingStrategy namingStrategy) + { + var schema = this.ParameterVisit(dataType: "array", dataFormat: null); + + var underlyingType = type.GetElementType() ?? type.GetGenericArguments()[0]; + var collection = VisitorCollection.CreateInstance(); + var items = collection.ParameterVisit(underlyingType, namingStrategy); + + schema.Items = items; + + return schema; + } + + /// + public override bool IsPayloadVisitable(Type type) + { + var isVisitable = this.IsVisitable(type); + + return isVisitable; + } + + /// + public override OpenApiSchema PayloadVisit(Type type, NamingStrategy namingStrategy) + { + var schema = this.PayloadVisit(dataType: "array", dataFormat: null); + + // Gets the schema for the underlying type. + var underlyingType = type.GetElementType() ?? type.GetGenericArguments()[0]; + var collection = VisitorCollection.CreateInstance(); + var items = collection.PayloadVisit(underlyingType, namingStrategy); + + // Adds the reference to the schema for the underlying type. + var reference = new OpenApiReference() + { + Type = ReferenceType.Schema, + Id = underlyingType.GetOpenApiReferenceId(isDictionary: false, isList: false, namingStrategy) + }; + + items.Reference = reference; + + schema.Items = items; + + return schema; + } + } +} diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/NullableObjectTypeVisitor.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/NullableObjectTypeVisitor.cs new file mode 100644 index 0000000..345bf44 --- /dev/null +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/NullableObjectTypeVisitor.cs @@ -0,0 +1,116 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; + +using Microsoft.OpenApi.Any; +using Microsoft.OpenApi.Models; + +using Newtonsoft.Json.Serialization; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors +{ + /// + /// This represents the type visitor for . + /// + public class NullableObjectTypeVisitor : TypeVisitor + { + /// + public override bool IsVisitable(Type type) + { + var isVisitable = this.IsVisitable(type, TypeCode.Object) && type.IsOpenApiNullable(); + + return isVisitable; + } + + /// + public override void Visit(IAcceptor acceptor, KeyValuePair type, NamingStrategy namingStrategy, params Attribute[] attributes) + { + var instance = acceptor as OpenApiSchemaAcceptor; + if (instance.IsNullOrDefault()) + { + return; + } + + // Gets the schema for the underlying type. + type.Value.IsOpenApiNullable(out var underlyingType); + + var types = new Dictionary() + { + { type.Key, underlyingType } + }; + var schemas = new Dictionary(); + + var subAcceptor = new OpenApiSchemaAcceptor() + { + Types = types, + Schemas = schemas, + }; + + var collection = VisitorCollection.CreateInstance(); + subAcceptor.Accept(collection, namingStrategy); + + // Adds the schema for the underlying type. + var name = subAcceptor.Schemas.First().Key; + var schema = subAcceptor.Schemas.First().Value; + schema.Nullable = true; + + // Adds the visibility property. + if (attributes.Any()) + { + var visibilityAttribute = attributes.OfType().SingleOrDefault(); + if (!visibilityAttribute.IsNullOrDefault()) + { + var extension = new OpenApiString(visibilityAttribute.Visibility.ToDisplayName()); + + schema.Extensions.Add("x-ms-visibility", extension); + } + } + + instance.Schemas.Add(name, schema); + } + + /// + public override bool IsParameterVisitable(Type type) + { + var isVisitable = this.IsVisitable(type); + + return isVisitable; + } + + /// + public override OpenApiSchema ParameterVisit(Type type, NamingStrategy namingStrategy) + { + type.IsOpenApiNullable(out var underlyingType); + var collection = VisitorCollection.CreateInstance(); + var schema = collection.ParameterVisit(underlyingType, namingStrategy); + + schema.Nullable = true; + + return schema; + } + + /// + public override bool IsPayloadVisitable(Type type) + { + var isVisitable = this.IsVisitable(type); + + return isVisitable; + } + + /// + public override OpenApiSchema PayloadVisit(Type type, NamingStrategy namingStrategy) + { + type.IsOpenApiNullable(out var underlyingType); + var collection = VisitorCollection.CreateInstance(); + var schema = collection.PayloadVisit(underlyingType, namingStrategy); + + schema.Nullable = true; + + return schema; + } + } +} diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/ObjectTypeVisitor.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/ObjectTypeVisitor.cs new file mode 100644 index 0000000..da4452f --- /dev/null +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/ObjectTypeVisitor.cs @@ -0,0 +1,206 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; + +using Microsoft.OpenApi.Models; + +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors +{ + /// + /// This represents the type visitor for . + /// + public class ObjectTypeVisitor : TypeVisitor + { + /// + public override bool IsVisitable(Type type) + { + var isVisitable = this.IsVisitable(type, TypeCode.Object); + if (type == typeof(Guid)) + { + isVisitable = false; + } + if (type == typeof(DateTime)) + { + isVisitable = false; + } + if (type == typeof(DateTimeOffset)) + { + isVisitable = false; + } + if (type.IsOpenApiNullable()) + { + isVisitable = false; + } + if (type.IsUnflaggedEnumType()) + { + isVisitable = false; + } + if (type.IsJObjectType()) + { + isVisitable = false; + } + if (type.HasRecursiveProperty()) + { + isVisitable = false; + } + + return isVisitable; + } + + /// + public override void Visit(IAcceptor acceptor, KeyValuePair type, NamingStrategy namingStrategy, params Attribute[] attributes) + { + var title = namingStrategy.GetPropertyName(type.Value.Name, hasSpecifiedName: false); + var name = this.Visit(acceptor, name: type.Key, title: title, dataType: "object", dataFormat: null, attributes: attributes); + + if (name.IsNullOrWhiteSpace()) + { + return; + } + + if (!this.IsNavigatable(type.Value)) + { + return; + } + + var instance = acceptor as OpenApiSchemaAcceptor; + if (instance.IsNullOrDefault()) + { + return; + } + + // Processes properties. + var properties = type.Value + .GetProperties(BindingFlags.Public | BindingFlags.Instance) + .Where(p => !p.ExistsCustomAttribute()) + .ToDictionary(p => p.GetJsonPropertyName(namingStrategy), p => p); + + this.ProcessProperties(instance, name, properties, namingStrategy); + + // Adds the reference. + var reference = new OpenApiReference() + { + Type = ReferenceType.Schema, + Id = type.Value.GetOpenApiReferenceId(isDictionary: false, isList: false, namingStrategy) + }; + + instance.Schemas[name].Reference = reference; + } + + /// + public override bool IsNavigatable(Type type) + { + if (type.IsJObjectType()) + { + return false; + } + + if (type.IsOpenApiNullable()) + { + return false; + } + + if (type.IsOpenApiArray()) + { + return false; + } + + if (type.IsOpenApiDictionary()) + { + return false; + } + + return true; + } + + /// + public override bool IsPayloadVisitable(Type type) + { + var isVisitable = this.IsVisitable(type); + + return isVisitable; + } + + /// + public override OpenApiSchema PayloadVisit(Type type, NamingStrategy namingStrategy) + { + return this.PayloadVisit(dataType: "object", dataFormat: null); + } + + private void ProcessProperties(IOpenApiSchemaAcceptor instance, string schemaName, Dictionary properties, NamingStrategy namingStrategy) + { + var schemas = new Dictionary(); + + var subAcceptor = new OpenApiSchemaAcceptor() + { + Properties = properties, + RootSchemas = instance.RootSchemas, + Schemas = schemas, + }; + + var collection = VisitorCollection.CreateInstance(); + subAcceptor.Accept(collection, namingStrategy); + + // Add required properties to schema. + var jsonPropertyAttributes = properties.Where(p => !p.Value.GetCustomAttribute(inherit: false).IsNullOrDefault()) + .Select(p => new KeyValuePair(p.Key, p.Value.GetCustomAttribute(inherit: false))) + .Where(p => p.Value.Required == Required.Always || p.Value.Required == Required.DisallowNull); + foreach (var attribute in jsonPropertyAttributes) + { + instance.Schemas[schemaName].Required.Add(attribute.Key); + } + + var jsonRequiredAttributes = properties.Where(p => !p.Value.GetCustomAttribute(inherit: false).IsNullOrDefault()) + .Select(p => new KeyValuePair(p.Key, p.Value.GetCustomAttribute(inherit: false))); + foreach (var attribute in jsonRequiredAttributes) + { + var attributeName = namingStrategy.GetPropertyName(attribute.Key, hasSpecifiedName: false); + if (instance.Schemas[schemaName].Required.Contains(attributeName)) + { + continue; + } + + instance.Schemas[schemaName].Required.Add(attributeName); + } + + instance.Schemas[schemaName].Properties = subAcceptor.Schemas; + + // Adds schemas to the root. + var schemasToBeAdded = subAcceptor.Schemas + .Where(p => !instance.Schemas.Keys.Contains(p.Key)) + .Where(p => p.Value.Type == "object" && + p.Value.Format.IsNullOrWhiteSpace() && + p.Value.Items.IsNullOrDefault() && + p.Value.AdditionalProperties.IsNullOrDefault()) + .ToDictionary(p => p.Value.Title, p => p.Value); + + foreach (var schema in schemasToBeAdded.Where(p => p.Key != "jObject" && p.Key != "jToken")) + { + if (instance.RootSchemas.ContainsKey(schema.Key)) + { + continue; + } + + instance.RootSchemas.Add(schema.Key, schema.Value); + } + + // Removes title of each property. + var subSchemas = instance.Schemas[schemaName].Properties; + subSchemas = subSchemas.Select(p => + { + p.Value.Title = null; + return new KeyValuePair(p.Key, p.Value); + }) + .ToDictionary(p => p.Key, p => p.Value); + + instance.Schemas[schemaName].Properties = subSchemas; + } + } +} diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/OpenApiSchemaAcceptor.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/OpenApiSchemaAcceptor.cs new file mode 100644 index 0000000..54ff4bd --- /dev/null +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/OpenApiSchemaAcceptor.cs @@ -0,0 +1,92 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; + +using Microsoft.OpenApi.Models; + +using Newtonsoft.Json.Serialization; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors +{ + /// + /// This represents the acceptor entity for . + /// + public class OpenApiSchemaAcceptor : IOpenApiSchemaAcceptor + { + /// + /// Initializes a new instance of the class. + /// + public OpenApiSchemaAcceptor() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// List of instances as key/value pair representing the root schemas. + /// List of instances as key/value pair. + /// List of objects. + public OpenApiSchemaAcceptor(Dictionary rootSchemas, Dictionary schemas, Dictionary types) + { + this.RootSchemas = rootSchemas.ThrowIfNullOrDefault(); + this.Schemas = schemas.ThrowIfNullOrDefault(); + this.Types = types.ThrowIfNullOrDefault(); + } + + /// + public Dictionary RootSchemas { get; set; } = new Dictionary(); + + /// + public Dictionary Schemas { get; set; } = new Dictionary(); + + /// + public Dictionary Types { get; set; } = new Dictionary(); + + /// + public Dictionary Properties { get; set; } = new Dictionary(); + + /// + public void Accept(VisitorCollection collection, NamingStrategy namingStrategy) + { + // Checks the properties only. + if (this.Properties.Any()) + { + foreach (var property in this.Properties) + { + var visibilityAttribute = property.Value.GetCustomAttribute(inherit: false); + + foreach (var visitor in collection.Visitors) + { + if (!visitor.IsVisitable(property.Value.PropertyType)) + { + continue; + } + + var type = new KeyValuePair(property.Key, property.Value.PropertyType); + visitor.Visit(this, type, namingStrategy, visibilityAttribute); + } + } + + return; + } + + // Checks the types only. + foreach (var type in this.Types) + { + foreach (var visitor in collection.Visitors) + { + if (!visitor.IsVisitable(type.Value)) + { + continue; + } + + visitor.Visit(this, type, namingStrategy); + } + } + } + } +} diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/RecursiveObjectTypeVisitor.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/RecursiveObjectTypeVisitor.cs new file mode 100644 index 0000000..47babac --- /dev/null +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/RecursiveObjectTypeVisitor.cs @@ -0,0 +1,224 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; + +using Microsoft.OpenApi.Models; + +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors +{ + /// + /// This represents the type visitor for that contains recursive properties. + /// + public class RecursiveObjectTypeVisitor : TypeVisitor + { + /// + public override bool IsVisitable(Type type) + { + var isVisitable = this.IsVisitable(type, TypeCode.Object) && type.HasRecursiveProperty(); + if (type == typeof(Guid)) + { + isVisitable = false; + } + if (type == typeof(DateTime)) + { + isVisitable = false; + } + if (type == typeof(DateTimeOffset)) + { + isVisitable = false; + } + if (type.IsOpenApiNullable()) + { + isVisitable = false; + } + if (type.IsUnflaggedEnumType()) + { + isVisitable = false; + } + if (type.IsJObjectType()) + { + isVisitable = false; + } + + return isVisitable; + } + + /// + public override void Visit(IAcceptor acceptor, KeyValuePair type, NamingStrategy namingStrategy, params Attribute[] attributes) + { + var title = namingStrategy.GetPropertyName(type.Value.Name, hasSpecifiedName: false); + var name = this.Visit(acceptor, name: type.Key, title: title, dataType: "object", dataFormat: null, attributes: attributes); + + if (name.IsNullOrWhiteSpace()) + { + return; + } + + if (!this.IsNavigatable(type.Value)) + { + return; + } + + var instance = acceptor as OpenApiSchemaAcceptor; + if (instance.IsNullOrDefault()) + { + return; + } + + // Processes non-recursive properties + var properties = type.Value + .GetProperties(BindingFlags.Public | BindingFlags.Instance) + .Where(p => !p.ExistsCustomAttribute()) + .Where(p => p.PropertyType != type.Value) + .ToDictionary(p => p.GetJsonPropertyName(namingStrategy), p => p); + + this.ProcessProperties(instance, name, properties, namingStrategy); + + // Processes recursive properties + var recursiveProperties = type.Value + .GetProperties(BindingFlags.Public | BindingFlags.Instance) + .Where(p => !p.ExistsCustomAttribute()) + .Where(p => p.PropertyType == type.Value) + .ToDictionary(p => p.GetJsonPropertyName(namingStrategy), p => p); + var recursiveSchemas = recursiveProperties.ToDictionary(p => p.Key, + p => new OpenApiSchema() + { + Type = "object", + Reference = new OpenApiReference() + { + Type = ReferenceType.Schema, + Id = p.Value.PropertyType.GetOpenApiReferenceId(isDictionary: false, isList: false, namingStrategy) + } + }); + foreach (var recursiveSchema in recursiveSchemas) + { + instance.Schemas[name].Properties.Add(recursiveSchema); + } + + // Adds the reference. + var reference = new OpenApiReference() + { + Type = ReferenceType.Schema, + Id = type.Value.GetOpenApiReferenceId(isDictionary: false, isList: false, namingStrategy) + }; + + instance.Schemas[name].Reference = reference; + } + + /// + public override bool IsNavigatable(Type type) + { + if (type.IsJObjectType()) + { + return false; + } + + if (type.IsOpenApiNullable()) + { + return false; + } + + if (type.IsOpenApiArray()) + { + return false; + } + + if (type.IsOpenApiDictionary()) + { + return false; + } + + return true; + } + + /// + public override bool IsPayloadVisitable(Type type) + { + var isVisitable = this.IsVisitable(type); + + return isVisitable; + } + + /// + public override OpenApiSchema PayloadVisit(Type type, NamingStrategy namingStrategy) + { + return this.PayloadVisit(dataType: "object", dataFormat: null); + } + + private void ProcessProperties(IOpenApiSchemaAcceptor instance, string schemaName, Dictionary properties, NamingStrategy namingStrategy) + { + var schemas = new Dictionary(); + + var subAcceptor = new OpenApiSchemaAcceptor() + { + Properties = properties, + RootSchemas = instance.RootSchemas, + Schemas = schemas, + }; + + var collection = VisitorCollection.CreateInstance(); + subAcceptor.Accept(collection, namingStrategy); + + // Add required properties to schema. + var jsonPropertyAttributes = properties.Where(p => !p.Value.GetCustomAttribute(inherit: false).IsNullOrDefault()) + .Select(p => new KeyValuePair(p.Key, p.Value.GetCustomAttribute(inherit: false))) + .Where(p => p.Value.Required == Required.Always || p.Value.Required == Required.DisallowNull); + foreach (var attribute in jsonPropertyAttributes) + { + instance.Schemas[schemaName].Required.Add(attribute.Key); + } + + var jsonRequiredAttributes = properties.Where(p => !p.Value.GetCustomAttribute(inherit: false).IsNullOrDefault()) + .Select(p => new KeyValuePair(p.Key, p.Value.GetCustomAttribute(inherit: false))); + foreach (var attribute in jsonRequiredAttributes) + { + var attributeName = namingStrategy.GetPropertyName(attribute.Key, hasSpecifiedName: false); + if (instance.Schemas[schemaName].Required.Contains(attributeName)) + { + continue; + } + + instance.Schemas[schemaName].Required.Add(attributeName); + } + + instance.Schemas[schemaName].Properties = subAcceptor.Schemas; + + // Adds schemas to the root. + var schemasToBeAdded = subAcceptor.Schemas + .Where(p => !instance.Schemas.Keys.Contains(p.Key)) + .Where(p => p.Value.Type == "object" && + p.Value.Format.IsNullOrWhiteSpace() && + p.Value.Items.IsNullOrDefault() && + p.Value.AdditionalProperties.IsNullOrDefault()) + .ToDictionary(p => p.Value.Title, p => p.Value); + + foreach (var schema in schemasToBeAdded.Where(p => p.Key != "jObject" && p.Key != "jToken")) + { + if (instance.RootSchemas.ContainsKey(schema.Key)) + { + continue; + } + + instance.RootSchemas.Add(schema.Key, schema.Value); + } + + // Removes title of each property. + var subSchemas = instance.Schemas[schemaName].Properties; + subSchemas = subSchemas.Select(p => + { + p.Value.Title = null; + return new KeyValuePair(p.Key, p.Value); + }) + .ToDictionary(p => p.Key, p => p.Value); + + instance.Schemas[schemaName].Properties = subSchemas; + } + } +} diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/SingleTypeVisitor.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/SingleTypeVisitor.cs new file mode 100644 index 0000000..16c434b --- /dev/null +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/SingleTypeVisitor.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; + +using Microsoft.OpenApi.Models; + +using Newtonsoft.Json.Serialization; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors +{ + /// + /// This represents the type visitor for . + /// + public class SingleTypeVisitor : TypeVisitor + { + /// + public override bool IsVisitable(Type type) + { + var isVisitable = this.IsVisitable(type, TypeCode.Single); + + return isVisitable; + } + + /// + public override void Visit(IAcceptor acceptor, KeyValuePair type, NamingStrategy namingStrategy, params Attribute[] attributes) + { + this.Visit(acceptor, name: type.Key, title: null, dataType: "number", dataFormat: "float", attributes: attributes); + } + + /// + public override bool IsParameterVisitable(Type type) + { + var isVisitable = this.IsVisitable(type); + + return isVisitable; + } + + /// + public override OpenApiSchema ParameterVisit(Type type, NamingStrategy namingStrategy) + { + return this.ParameterVisit(dataType: "number", dataFormat: "float"); + } + + /// + public override bool IsPayloadVisitable(Type type) + { + var isVisitable = this.IsVisitable(type); + + return isVisitable; + } + + /// + public override OpenApiSchema PayloadVisit(Type type, NamingStrategy namingStrategy) + { + return this.PayloadVisit(dataType: "number", dataFormat: "float"); + } + } +} diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/StringEnumTypeVisitor.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/StringEnumTypeVisitor.cs new file mode 100644 index 0000000..0637a4e --- /dev/null +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/StringEnumTypeVisitor.cs @@ -0,0 +1,114 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; + +using Microsoft.OpenApi.Any; +using Microsoft.OpenApi.Models; + +using Newtonsoft.Json.Converters; +using Newtonsoft.Json.Serialization; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors +{ + /// + /// This represents the type visitor for type enum. + /// + public class StringEnumTypeVisitor : TypeVisitor + { + /// + public override bool IsVisitable(Type type) + { + var isVisitable = (this.IsVisitable(type, TypeCode.Int16) || this.IsVisitable(type, TypeCode.Int32) || this.IsVisitable(type, TypeCode.Int64)) && + type.IsUnflaggedEnumType() && + type.HasJsonConverterAttribute() + ; + + return isVisitable; + } + + /// + public override void Visit(IAcceptor acceptor, KeyValuePair type, NamingStrategy namingStrategy, params Attribute[] attributes) + { + var name = type.Key; + + var instance = acceptor as OpenApiSchemaAcceptor; + if (instance.IsNullOrDefault()) + { + return; + } + + // Adds enum values to the schema. + var enums = type.Value.ToOpenApiStringCollection(namingStrategy); + + var schema = new OpenApiSchema() + { + Type = "string", + Format = null, + Enum = enums, + Default = enums.First() + }; + + // Adds the visibility property. + if (attributes.Any()) + { + var visibilityAttribute = attributes.OfType().SingleOrDefault(); + if (!visibilityAttribute.IsNullOrDefault()) + { + var extension = new OpenApiString(visibilityAttribute.Visibility.ToDisplayName()); + + schema.Extensions.Add("x-ms-visibility", extension); + } + } + + instance.Schemas.Add(name, schema); + } + + /// + public override bool IsParameterVisitable(Type type) + { + var isVisitable = this.IsVisitable(type); + + return isVisitable; + } + + /// + public override OpenApiSchema ParameterVisit(Type type, NamingStrategy namingStrategy) + { + var schema = this.ParameterVisit(dataType: "string", dataFormat: null); + + // Adds enum values to the schema. + var enums = type.ToOpenApiStringCollection(namingStrategy); + + schema.Enum = enums; + schema.Default = enums.First(); + + return schema; + } + + /// + public override bool IsPayloadVisitable(Type type) + { + var isVisitable = this.IsVisitable(type); + + return isVisitable; + } + + /// + public override OpenApiSchema PayloadVisit(Type type, NamingStrategy namingStrategy) + { + var schema = this.PayloadVisit(dataType: "string", dataFormat: null); + + // Adds enum values to the schema. + var enums = type.ToOpenApiStringCollection(namingStrategy); + + schema.Enum = enums; + schema.Default = enums.First(); + + return schema; + } + } +} diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/StringTypeVisitor.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/StringTypeVisitor.cs new file mode 100644 index 0000000..9124618 --- /dev/null +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/StringTypeVisitor.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; + +using Microsoft.OpenApi.Models; + +using Newtonsoft.Json.Serialization; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors +{ + /// + /// This represents the type visitor for . + /// + public class StringTypeVisitor : TypeVisitor + { + /// + public override bool IsVisitable(Type type) + { + var isVisitable = this.IsVisitable(type, TypeCode.String); + + return isVisitable; + } + + /// + public override void Visit(IAcceptor acceptor, KeyValuePair type, NamingStrategy namingStrategy, params Attribute[] attributes) + { + this.Visit(acceptor, name: type.Key, title: null, dataType: "string", dataFormat: null, attributes: attributes); + } + + /// + public override bool IsParameterVisitable(Type type) + { + var isVisitable = this.IsVisitable(type); + + return isVisitable; + } + + /// + public override OpenApiSchema ParameterVisit(Type type, NamingStrategy namingStrategy) + { + return this.ParameterVisit(dataType: "string", dataFormat: null); + } + + /// + public override bool IsPayloadVisitable(Type type) + { + var isVisitable = this.IsVisitable(type); + + return isVisitable; + } + + /// + public override OpenApiSchema PayloadVisit(Type type, NamingStrategy namingStrategy) + { + return this.PayloadVisit(dataType: "string", dataFormat: null); + } + } +} diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/TypeVisitor.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/TypeVisitor.cs new file mode 100644 index 0000000..3c1c18a --- /dev/null +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/TypeVisitor.cs @@ -0,0 +1,206 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; + +using Microsoft.OpenApi.Any; +using Microsoft.OpenApi.Models; + +using Newtonsoft.Json.Serialization; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors +{ + /// + /// This represents the visitor entity for type. This MUST be inherited. + /// + public abstract class TypeVisitor : IVisitor + { + /// + /// Gets the object. + /// + protected Type Type { get; private set; } + + /// + public virtual bool IsVisitable(Type type) + { + return false; + } + + /// + public virtual void Visit(IAcceptor acceptor, KeyValuePair type, NamingStrategy namingStrategy, params Attribute[] attributes) + { + return; + } + + /// + public virtual bool IsNavigatable(Type type) + { + return false; + } + + /// + public virtual bool IsParameterVisitable(Type type) + { + return false; + } + + /// + public virtual OpenApiSchema ParameterVisit(Type type, NamingStrategy namingStrategy) + { + return default; + } + + /// + public virtual bool IsPayloadVisitable(Type type) + { + return false; + } + + /// + public virtual OpenApiSchema PayloadVisit(Type type, NamingStrategy namingStrategy) + { + return default; + } + + /// + /// Checks whether the type is visitable or not. + /// + /// Type to check. + /// value. + /// Returns True, if the type is visitable; otherwise returns False. + protected bool IsVisitable(Type type, TypeCode code) + { + var @enum = Type.GetTypeCode(type); + var isVisitable = @enum == code; + + if (isVisitable) + { + this.Type = type; + } + + return isVisitable; + } + + /// + /// Checks whether the type can be referenced or not. + /// + /// Type to check. + /// Returns True, if the type can be referenced; otherwise returns False. + protected bool IsReferential(Type type) + { + var @enum = Type.GetTypeCode(type); + var isReferential = @enum == TypeCode.Object; + + if (type == typeof(Guid)) + { + isReferential = false; + } + if (type == typeof(DateTime)) + { + isReferential = false; + } + if (type == typeof(DateTimeOffset)) + { + isReferential = false; + } + if (type.IsOpenApiNullable()) + { + isReferential = false; + } + if (type.IsUnflaggedEnumType()) + { + isReferential = false; + } + if (type.IsJObjectType()) + { + isReferential = false; + } + + return isReferential; + } + + /// + /// Visits and processes the acceptor. + /// + /// instance. + /// Property name. + /// Type name. + /// Data type. + /// Data format. + /// List of attribute instances. + /// Returns the name as the schema key. + protected string Visit(IAcceptor acceptor, string name, string title, string dataType, string dataFormat, params Attribute[] attributes) + { + var instance = acceptor as OpenApiSchemaAcceptor; + if (instance.IsNullOrDefault()) + { + return null; + } + + if (instance.Schemas.ContainsKey(name)) + { + return null; + } + + var schema = new OpenApiSchema() + { + Title = title, + Type = dataType, + Format = dataFormat + }; + + // Adds the visibility property. + if (attributes.Any()) + { + var visibilityAttribute = attributes.OfType().SingleOrDefault(); + if (!visibilityAttribute.IsNullOrDefault()) + { + var extension = new OpenApiString(visibilityAttribute.Visibility.ToDisplayName()); + + schema.Extensions.Add("x-ms-visibility", extension); + } + } + + instance.Schemas.Add(name, schema); + + return name; + } + + /// + /// Visits and processes the for parameters. + /// + /// Data type. + /// Data format. + /// Returns instance. + protected OpenApiSchema ParameterVisit(string dataType, string dataFormat) + { + var schema = new OpenApiSchema() + { + Type = dataType, + Format = dataFormat + }; + + return schema; + } + + /// + /// Visits and processes the for payloads. + /// + /// Data type. + /// Data format. + /// Returns instance. + protected OpenApiSchema PayloadVisit(string dataType, string dataFormat) + { + var schema = new OpenApiSchema() + { + Type = dataType, + Format = dataFormat + }; + + return schema; + } + } +} diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/VisitorCollection.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/VisitorCollection.cs new file mode 100644 index 0000000..787822a --- /dev/null +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/Visitors/VisitorCollection.cs @@ -0,0 +1,103 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; + +using Microsoft.OpenApi.Models; + +using Newtonsoft.Json.Serialization; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors +{ + /// + /// This represents the collection entity for instances. + /// + public class VisitorCollection + { + /// + /// Initializes a new instance of the class. + /// + public VisitorCollection() + { + this.Visitors = new List(); + } + + /// + /// Initializes a new instance of the class. + /// + /// List of instances. + public VisitorCollection(List visitors) + { + this.Visitors = visitors.ThrowIfNullOrDefault(); + } + + /// + /// Gets the list of instances. + /// + public List Visitors { get; } + + /// + /// Creates a new instance of the class. + /// + /// Returns the instance. + public static VisitorCollection CreateInstance() + { + var visitors = typeof(IVisitor).Assembly + .GetTypes() + .Where(p => p.Name.EndsWith("Visitor") && p.IsClass && !p.IsAbstract) + .Select(p => (IVisitor)Activator.CreateInstance(p)) + .ToList(); + var collection = new VisitorCollection(visitors); + + return collection; + } + + /// + /// Processes the parameter type. + /// + /// Type of the parameter. + /// instance. + /// Returns instance. + public OpenApiSchema ParameterVisit(Type type, NamingStrategy namingStrategy) + { + var schema = default(OpenApiSchema); + foreach (var visitor in this.Visitors) + { + if (!visitor.IsParameterVisitable(type)) + { + continue; + } + + schema = visitor.ParameterVisit(type, namingStrategy); + break; + } + + return schema; + } + + /// + /// Processes the request/response payload type. + /// + /// Type of the payload. + /// instance. + /// Returns instance. + public OpenApiSchema PayloadVisit(Type type, NamingStrategy namingStrategy) + { + var schema = default(OpenApiSchema); + foreach (var visitor in this.Visitors) + { + if (!visitor.IsPayloadVisitable(type)) + { + continue; + } + + schema = visitor.PayloadVisit(type, namingStrategy); + break; + } + + return schema; + } + } +} diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/dist/favicon-16x16.png b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/dist/favicon-16x16.png similarity index 100% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/dist/favicon-16x16.png rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/dist/favicon-16x16.png diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/dist/favicon-32x32.png b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/dist/favicon-32x32.png similarity index 100% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/dist/favicon-32x32.png rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/dist/favicon-32x32.png diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/dist/index.html b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/dist/index.html similarity index 100% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/dist/index.html rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/dist/index.html diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/dist/oauth2-redirect.html b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/dist/oauth2-redirect.html similarity index 100% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/dist/oauth2-redirect.html rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/dist/oauth2-redirect.html diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/dist/swagger-ui-bundle.js b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/dist/swagger-ui-bundle.js similarity index 100% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/dist/swagger-ui-bundle.js rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/dist/swagger-ui-bundle.js diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/dist/swagger-ui-bundle.js.map b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/dist/swagger-ui-bundle.js.map similarity index 100% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/dist/swagger-ui-bundle.js.map rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/dist/swagger-ui-bundle.js.map diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/dist/swagger-ui-standalone-preset.js b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/dist/swagger-ui-standalone-preset.js similarity index 100% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/dist/swagger-ui-standalone-preset.js rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/dist/swagger-ui-standalone-preset.js diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/dist/swagger-ui-standalone-preset.js.map b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/dist/swagger-ui-standalone-preset.js.map similarity index 100% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/dist/swagger-ui-standalone-preset.js.map rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/dist/swagger-ui-standalone-preset.js.map diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/dist/swagger-ui.css b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/dist/swagger-ui.css similarity index 100% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/dist/swagger-ui.css rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/dist/swagger-ui.css diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/dist/swagger-ui.css.map b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/dist/swagger-ui.css.map similarity index 100% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/dist/swagger-ui.css.map rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/dist/swagger-ui.css.map diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/dist/swagger-ui.js b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/dist/swagger-ui.js similarity index 100% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/dist/swagger-ui.js rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/dist/swagger-ui.js diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/dist/swagger-ui.js.map b/src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/dist/swagger-ui.js.map similarity index 100% rename from src/Aliencube.AzureFunctions.Extensions.OpenApi/dist/swagger-ui.js.map rename to src/Aliencube.AzureFunctions.Extensions.OpenApi.Core/dist/swagger-ui.js.map diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Aliencube.AzureFunctions.Extensions.OpenApi.csproj b/src/Aliencube.AzureFunctions.Extensions.OpenApi/Aliencube.AzureFunctions.Extensions.OpenApi.csproj index c784226..8babcf8 100644 --- a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Aliencube.AzureFunctions.Extensions.OpenApi.csproj +++ b/src/Aliencube.AzureFunctions.Extensions.OpenApi/Aliencube.AzureFunctions.Extensions.OpenApi.csproj @@ -4,7 +4,7 @@ net461;netstandard2.0 true true -    $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb + $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb true Aliencube.AzureFunctions.Extensions.OpenApi Aliencube @@ -34,19 +34,8 @@ bin\Release\netstandard2.0\Aliencube.AzureFunctions.Extensions.OpenApi.xml - - - - - - - - - - - - + @@ -55,22 +44,8 @@ - - - - - - - - - - - - - - - + diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/OpenApiPayloadAttributeExtensions.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/OpenApiPayloadAttributeExtensions.cs deleted file mode 100644 index 4db7dac..0000000 --- a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/OpenApiPayloadAttributeExtensions.cs +++ /dev/null @@ -1,88 +0,0 @@ -using Aliencube.AzureFunctions.Extensions.OpenApi.Attributes; - -using Microsoft.OpenApi.Models; - -using Newtonsoft.Json.Serialization; - -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Extensions -{ - /// - /// This represents the extension entity for . - /// - public static class OpenApiPayloadAttributeExtensions - { - /// - /// Converts to . - /// - /// Type of payload attribute inheriting . - /// OpenApi payload attribute. - /// instance to create the JSON schema from .NET Types. - /// instance. - public static OpenApiMediaType ToOpenApiMediaType(this T attribute, NamingStrategy namingStrategy = null) where T : OpenApiPayloadAttribute - { - attribute.ThrowIfNullOrDefault(); - - var isJObject = attribute.BodyType.IsJObjectType(); - var isDictionary = attribute.BodyType.IsOpenApiDictionary(); - var isList = attribute.BodyType.IsOpenApiArray(); - var isGeneric = attribute.BodyType.IsGenericType; - var isSimpleType = (isDictionary || isList) - ? attribute.BodyType.GetOpenApiSubType().IsSimpleType() - : attribute.BodyType.IsSimpleType(); - - var reference = new OpenApiReference() - { - Type = ReferenceType.Schema, - Id = attribute.BodyType.GetOpenApiReferenceId(isDictionary, isList) - }; - - var schema = new OpenApiSchema() { Reference = reference }; - - if (isJObject) - { - schema = new OpenApiSchema() - { - Type = "object" - }; - } - else if (isDictionary) - { - schema = new OpenApiSchema() - { - Type = "object", - AdditionalProperties = isSimpleType - ? attribute.BodyType.GetOpenApiSubType().ToOpenApiSchema(namingStrategy) - : schema - }; - } - else if (isList) - { - schema = new OpenApiSchema() - { - Type = "array", - Items = isSimpleType - ? attribute.BodyType.GetOpenApiSubType().ToOpenApiSchema(namingStrategy) - : schema - }; - } - else if (isGeneric) - { - reference = new OpenApiReference() - { - Type = ReferenceType.Schema, - Id = attribute.BodyType.GetOpenApiRootReferenceId() - }; - - schema = new OpenApiSchema() { Reference = reference }; - } - else if (isSimpleType) - { - schema = attribute.BodyType.ToOpenApiSchema(namingStrategy); - } - - var mediaType = new OpenApiMediaType() { Schema = schema }; - - return mediaType; - } - } -} diff --git a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/PropertyInfoExtensions.cs b/src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/PropertyInfoExtensions.cs deleted file mode 100644 index 786f35c..0000000 --- a/src/Aliencube.AzureFunctions.Extensions.OpenApi/Extensions/PropertyInfoExtensions.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System.Reflection; - -using Newtonsoft.Json; - -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Extensions -{ - /// - /// This represents the extension entity for class. - /// - public static class PropertyInfoExtensions - { - /// - /// Gets the name from instance. - /// - /// instance. - /// Returns the name from instance. - public static string GetJsonPropertyName(this PropertyInfo element) - { - if (element.ExistsCustomAttribute()) - { - var name = element.GetCustomAttribute().PropertyName; - - return name; - - } - - return element.Name; - } - } -} \ No newline at end of file diff --git a/templates/OpenApiEndpints/IOpenApiHttpTriggerContext.cs b/templates/OpenApiEndpints/IOpenApiHttpTriggerContext.cs index 030703e..519e3ef 100644 --- a/templates/OpenApiEndpints/IOpenApiHttpTriggerContext.cs +++ b/templates/OpenApiEndpints/IOpenApiHttpTriggerContext.cs @@ -1,8 +1,9 @@ using System.Reflection; -using Aliencube.AzureFunctions.Extensions.OpenApi.Abstractions; -using Aliencube.AzureFunctions.Extensions.OpenApi.Configurations; -using Aliencube.AzureFunctions.Extensions.OpenApi.Enums; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Configurations; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors; using Microsoft.OpenApi; using Microsoft.OpenApi.Models; @@ -47,6 +48,12 @@ public interface IOpenApiHttpTriggerContext /// Returns the executing assembly. Assembly GetExecutingAssembly(); + /// + /// Gets the instance. + /// + /// Returns the instance. + VisitorCollection GetVisitorCollection(); + /// /// Gets the value. /// diff --git a/templates/OpenApiEndpints/OpenApiHttpTrigger.cs b/templates/OpenApiEndpints/OpenApiHttpTrigger.cs index 5d859e7..beafb5e 100644 --- a/templates/OpenApiEndpints/OpenApiHttpTrigger.cs +++ b/templates/OpenApiEndpints/OpenApiHttpTrigger.cs @@ -2,8 +2,8 @@ using System.Net; using System.Threading.Tasks; -using Aliencube.AzureFunctions.Extensions.OpenApi.Attributes; -using Aliencube.AzureFunctions.Extensions.OpenApi.Extensions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; @@ -35,7 +35,7 @@ public static class OpenApiHttpTrigger [FunctionName(nameof(OpenApiHttpTrigger.RenderSwaggerDocument))] [OpenApiIgnore] public static async Task RenderSwaggerDocument( - [HttpTrigger(AuthorizationLevel.Function, "get", Route = "swagger.{extension}")] HttpRequest req, + [HttpTrigger(AuthorizationLevel.Function, "GET", Route = "swagger.{extension}")] HttpRequest req, string extension, ILogger log) { @@ -45,7 +45,9 @@ public static async Task RenderSwaggerDocument( .InitialiseDocument() .AddMetadata(context.OpenApiInfo) .AddServer(req, context.HttpSettings.RoutePrefix) - .Build(context.GetExecutingAssembly(), context.NamingStrategy) + .AddNamingStrategy(context.NamingStrategy) + .AddVisitors(context.GetVisitorCollection()) + .Build(context.GetExecutingAssembly()) .RenderAsync(context.GetOpenApiSpecVersion(V2), context.GetOpenApiFormat(extension)) .ConfigureAwait(false); @@ -70,7 +72,7 @@ public static async Task RenderSwaggerDocument( [FunctionName(nameof(OpenApiHttpTrigger.RenderOpenApiDocument))] [OpenApiIgnore] public static async Task RenderOpenApiDocument( - [HttpTrigger(AuthorizationLevel.Function, "get", Route = "openapi/{version}.{extension}")] HttpRequest req, + [HttpTrigger(AuthorizationLevel.Function, "GET", Route = "openapi/{version}.{extension}")] HttpRequest req, string version, string extension, ILogger log) @@ -81,7 +83,9 @@ public static async Task RenderOpenApiDocument( .InitialiseDocument() .AddMetadata(context.OpenApiInfo) .AddServer(req, context.HttpSettings.RoutePrefix) - .Build(context.GetExecutingAssembly(), context.NamingStrategy) + .AddNamingStrategy(context.NamingStrategy) + .AddVisitors(context.GetVisitorCollection()) + .Build(context.GetExecutingAssembly()) .RenderAsync(context.GetOpenApiSpecVersion(version), context.GetOpenApiFormat(extension)) .ConfigureAwait(false); @@ -104,7 +108,7 @@ public static async Task RenderOpenApiDocument( [FunctionName(nameof(OpenApiHttpTrigger.RenderSwaggerUI))] [OpenApiIgnore] public static async Task RenderSwaggerUI( - [HttpTrigger(AuthorizationLevel.Function, "get", Route = "swagger/ui")] HttpRequest req, + [HttpTrigger(AuthorizationLevel.Function, "GET", Route = "swagger/ui")] HttpRequest req, ILogger log) { log.LogInformation($"SwaggerUI page was requested."); diff --git a/templates/OpenApiEndpints/OpenApiHttpTriggerContext.cs b/templates/OpenApiEndpints/OpenApiHttpTriggerContext.cs index cc0eb61..f9bf3a9 100644 --- a/templates/OpenApiEndpints/OpenApiHttpTriggerContext.cs +++ b/templates/OpenApiEndpints/OpenApiHttpTriggerContext.cs @@ -1,11 +1,13 @@ using System; using System.Reflection; -using Aliencube.AzureFunctions.Extensions.OpenApi.Abstractions; -using Aliencube.AzureFunctions.Extensions.OpenApi.Configurations; -using Aliencube.AzureFunctions.Extensions.OpenApi.Enums; -using Aliencube.AzureFunctions.Extensions.OpenApi.Extensions; -using Aliencube.AzureFunctions.Extensions.OpenApi.Resolvers; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Configurations; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Resolvers; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors; using Microsoft.OpenApi; using Microsoft.OpenApi.Models; @@ -30,7 +32,8 @@ public OpenApiHttpTriggerContext() this.HttpSettings = host.GetHttpSettings(); var filter = new RouteConstraintFilter(); - var helper = new DocumentHelper(filter); + var acceptor = new OpenApiSchemaAcceptor(); + var helper = new DocumentHelper(filter, acceptor); this.Document = new Document(helper); this.SwaggerUI = new SwaggerUI(); @@ -57,6 +60,14 @@ public virtual Assembly GetExecutingAssembly() return Assembly.GetExecutingAssembly(); } + /// + public virtual VisitorCollection GetVisitorCollection() + { + var collection = VisitorCollection.CreateInstance(); + + return collection; + } + /// public virtual OpenApiSpecVersion GetOpenApiSpecVersion(string version = "v2") { diff --git a/templates/OpenApiEndpints/OpenApiHttpTriggerV1.cs b/templates/OpenApiEndpints/OpenApiHttpTriggerV1.cs index 0a1f004..7f80a78 100644 --- a/templates/OpenApiEndpints/OpenApiHttpTriggerV1.cs +++ b/templates/OpenApiEndpints/OpenApiHttpTriggerV1.cs @@ -4,8 +4,8 @@ using System.Text; using System.Threading.Tasks; -using Aliencube.AzureFunctions.Extensions.OpenApi.Attributes; -using Aliencube.AzureFunctions.Extensions.OpenApi.Extensions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; using Microsoft.Azure.WebJobs; using Microsoft.Azure.WebJobs.Extensions.Http; @@ -34,7 +34,7 @@ public static class OpenApiHttpTrigger [FunctionName(nameof(OpenApiHttpTrigger.RenderSwaggerDocumentInJson))] [OpenApiIgnore] public static async Task RenderSwaggerDocumentInJson( - [HttpTrigger(AuthorizationLevel.Function, "get", Route = "swagger.json")] HttpRequestMessage req, + [HttpTrigger(AuthorizationLevel.Function, "GET", Route = "swagger.json")] HttpRequestMessage req, ILogger log) { log.LogInformation($"swagger.json was requested."); @@ -43,7 +43,9 @@ public static async Task RenderSwaggerDocumentInJson( .InitialiseDocument() .AddMetadata(context.OpenApiInfo) .AddServer(req, context.HttpSettings.RoutePrefix) - .Build(context.GetExecutingAssembly(), context.NamingStrategy) + .AddNamingStrategy(context.NamingStrategy) + .AddVisitors(context.GetVisitorCollection()) + .Build(context.GetExecutingAssembly()) .RenderAsync(context.GetOpenApiSpecVersion(V2), context.GetOpenApiFormat(JSON)) .ConfigureAwait(false); @@ -62,7 +64,7 @@ public static async Task RenderSwaggerDocumentInJson( [FunctionName(nameof(OpenApiHttpTrigger.RenderSwaggerDocumentInYml))] [OpenApiIgnore] public static async Task RenderSwaggerDocumentInYml( - [HttpTrigger(AuthorizationLevel.Function, "get", Route = "swagger.yml")] HttpRequestMessage req, + [HttpTrigger(AuthorizationLevel.Function, "GET", Route = "swagger.yml")] HttpRequestMessage req, ILogger log) { log.LogInformation($"swagger.yaml was requested."); @@ -71,7 +73,9 @@ public static async Task RenderSwaggerDocumentInYml( .InitialiseDocument() .AddMetadata(context.OpenApiInfo) .AddServer(req, context.HttpSettings.RoutePrefix) - .Build(context.GetExecutingAssembly(), context.NamingStrategy) + .AddNamingStrategy(context.NamingStrategy) + .AddVisitors(context.GetVisitorCollection()) + .Build(context.GetExecutingAssembly()) .RenderAsync(context.GetOpenApiSpecVersion(V2), context.GetOpenApiFormat(YAML)) .ConfigureAwait(false); @@ -90,7 +94,7 @@ public static async Task RenderSwaggerDocumentInYml( [FunctionName(nameof(OpenApiHttpTrigger.RenderSwaggerDocumentInYaml))] [OpenApiIgnore] public static async Task RenderSwaggerDocumentInYaml( - [HttpTrigger(AuthorizationLevel.Function, "get", Route = "swagger.yaml")] HttpRequestMessage req, + [HttpTrigger(AuthorizationLevel.Function, "GET", Route = "swagger.yaml")] HttpRequestMessage req, ILogger log) { log.LogInformation($"swagger.yaml was requested."); @@ -99,7 +103,9 @@ public static async Task RenderSwaggerDocumentInYaml( .InitialiseDocument() .AddMetadata(context.OpenApiInfo) .AddServer(req, context.HttpSettings.RoutePrefix) - .Build(context.GetExecutingAssembly(), context.NamingStrategy) + .AddNamingStrategy(context.NamingStrategy) + .AddVisitors(context.GetVisitorCollection()) + .Build(context.GetExecutingAssembly()) .RenderAsync(context.GetOpenApiSpecVersion(V2), context.GetOpenApiFormat(YAML)) .ConfigureAwait(false); @@ -118,7 +124,7 @@ public static async Task RenderSwaggerDocumentInYaml( [FunctionName(nameof(OpenApiHttpTrigger.RenderOpenApiDocumentV2InJson))] [OpenApiIgnore] public static async Task RenderOpenApiDocumentV2InJson( - [HttpTrigger(AuthorizationLevel.Function, "get", Route = "openapi/v2.json")] HttpRequestMessage req, + [HttpTrigger(AuthorizationLevel.Function, "GET", Route = "openapi/v2.json")] HttpRequestMessage req, ILogger log) { log.LogInformation($"v2.json was requested."); @@ -127,7 +133,9 @@ public static async Task RenderOpenApiDocumentV2InJson( .InitialiseDocument() .AddMetadata(context.OpenApiInfo) .AddServer(req, context.HttpSettings.RoutePrefix) - .Build(context.GetExecutingAssembly(), context.NamingStrategy) + .AddNamingStrategy(context.NamingStrategy) + .AddVisitors(context.GetVisitorCollection()) + .Build(context.GetExecutingAssembly()) .RenderAsync(context.GetOpenApiSpecVersion(V2), context.GetOpenApiFormat(JSON)) .ConfigureAwait(false); @@ -146,7 +154,7 @@ public static async Task RenderOpenApiDocumentV2InJson( [FunctionName(nameof(OpenApiHttpTrigger.RenderOpenApiDocumentV2InYml))] [OpenApiIgnore] public static async Task RenderOpenApiDocumentV2InYml( - [HttpTrigger(AuthorizationLevel.Function, "get", Route = "openapi/v2.yml")] HttpRequestMessage req, + [HttpTrigger(AuthorizationLevel.Function, "GET", Route = "openapi/v2.yml")] HttpRequestMessage req, ILogger log) { log.LogInformation($"v2.yaml was requested."); @@ -155,7 +163,9 @@ public static async Task RenderOpenApiDocumentV2InYml( .InitialiseDocument() .AddMetadata(context.OpenApiInfo) .AddServer(req, context.HttpSettings.RoutePrefix) - .Build(context.GetExecutingAssembly(), context.NamingStrategy) + .AddNamingStrategy(context.NamingStrategy) + .AddVisitors(context.GetVisitorCollection()) + .Build(context.GetExecutingAssembly()) .RenderAsync(context.GetOpenApiSpecVersion(V2), context.GetOpenApiFormat(YAML)) .ConfigureAwait(false); @@ -174,7 +184,7 @@ public static async Task RenderOpenApiDocumentV2InYml( [FunctionName(nameof(OpenApiHttpTrigger.RenderOpenApiDocumentV2InYaml))] [OpenApiIgnore] public static async Task RenderOpenApiDocumentV2InYaml( - [HttpTrigger(AuthorizationLevel.Function, "get", Route = "openapi/v2.yaml")] HttpRequestMessage req, + [HttpTrigger(AuthorizationLevel.Function, "GET", Route = "openapi/v2.yaml")] HttpRequestMessage req, ILogger log) { log.LogInformation($"v2.yaml was requested."); @@ -183,7 +193,9 @@ public static async Task RenderOpenApiDocumentV2InYaml( .InitialiseDocument() .AddMetadata(context.OpenApiInfo) .AddServer(req, context.HttpSettings.RoutePrefix) - .Build(context.GetExecutingAssembly(), context.NamingStrategy) + .AddNamingStrategy(context.NamingStrategy) + .AddVisitors(context.GetVisitorCollection()) + .Build(context.GetExecutingAssembly()) .RenderAsync(context.GetOpenApiSpecVersion(V2), context.GetOpenApiFormat(YAML)) .ConfigureAwait(false); @@ -202,7 +214,7 @@ public static async Task RenderOpenApiDocumentV2InYaml( [FunctionName(nameof(OpenApiHttpTrigger.RenderOpenApiDocumentV3InJson))] [OpenApiIgnore] public static async Task RenderOpenApiDocumentV3InJson( - [HttpTrigger(AuthorizationLevel.Function, "get", Route = "openapi/v3.json")] HttpRequestMessage req, + [HttpTrigger(AuthorizationLevel.Function, "GET", Route = "openapi/v3.json")] HttpRequestMessage req, ILogger log) { log.LogInformation($"v3.json was requested."); @@ -211,7 +223,9 @@ public static async Task RenderOpenApiDocumentV3InJson( .InitialiseDocument() .AddMetadata(context.OpenApiInfo) .AddServer(req, context.HttpSettings.RoutePrefix) - .Build(context.GetExecutingAssembly(), context.NamingStrategy) + .AddNamingStrategy(context.NamingStrategy) + .AddVisitors(context.GetVisitorCollection()) + .Build(context.GetExecutingAssembly()) .RenderAsync(context.GetOpenApiSpecVersion(V3), context.GetOpenApiFormat(JSON)) .ConfigureAwait(false); @@ -230,7 +244,7 @@ public static async Task RenderOpenApiDocumentV3InJson( [FunctionName(nameof(OpenApiHttpTrigger.RenderOpenApiDocumentV3InYml))] [OpenApiIgnore] public static async Task RenderOpenApiDocumentV3InYml( - [HttpTrigger(AuthorizationLevel.Function, "get", Route = "openapi/v3.yml")] HttpRequestMessage req, + [HttpTrigger(AuthorizationLevel.Function, "GET", Route = "openapi/v3.yml")] HttpRequestMessage req, ILogger log) { log.LogInformation($"v3.yaml was requested."); @@ -239,7 +253,9 @@ public static async Task RenderOpenApiDocumentV3InYml( .InitialiseDocument() .AddMetadata(context.OpenApiInfo) .AddServer(req, context.HttpSettings.RoutePrefix) - .Build(context.GetExecutingAssembly(), context.NamingStrategy) + .AddNamingStrategy(context.NamingStrategy) + .AddVisitors(context.GetVisitorCollection()) + .Build(context.GetExecutingAssembly()) .RenderAsync(context.GetOpenApiSpecVersion(V3), context.GetOpenApiFormat(YAML)) .ConfigureAwait(false); @@ -258,7 +274,7 @@ public static async Task RenderOpenApiDocumentV3InYml( [FunctionName(nameof(OpenApiHttpTrigger.RenderOpenApiDocumentV3InYaml))] [OpenApiIgnore] public static async Task RenderOpenApiDocumentV3InYaml( - [HttpTrigger(AuthorizationLevel.Function, "get", Route = "openapi/v3.yaml")] HttpRequestMessage req, + [HttpTrigger(AuthorizationLevel.Function, "GET", Route = "openapi/v3.yaml")] HttpRequestMessage req, ILogger log) { log.LogInformation($"v3.yaml was requested."); @@ -267,7 +283,9 @@ public static async Task RenderOpenApiDocumentV3InYaml( .InitialiseDocument() .AddMetadata(context.OpenApiInfo) .AddServer(req, context.HttpSettings.RoutePrefix) - .Build(context.GetExecutingAssembly(), context.NamingStrategy) + .AddNamingStrategy(context.NamingStrategy) + .AddVisitors(context.GetVisitorCollection()) + .Build(context.GetExecutingAssembly()) .RenderAsync(context.GetOpenApiSpecVersion(V3), context.GetOpenApiFormat(YAML)) .ConfigureAwait(false); @@ -286,7 +304,7 @@ public static async Task RenderOpenApiDocumentV3InYaml( [FunctionName(nameof(OpenApiHttpTrigger.RenderSwaggerUI))] [OpenApiIgnore] public static async Task RenderSwaggerUI( - [HttpTrigger(AuthorizationLevel.Function, "get", Route = "swagger/ui")] HttpRequestMessage req, + [HttpTrigger(AuthorizationLevel.Function, "GET", Route = "swagger/ui")] HttpRequestMessage req, ILogger log) { log.LogInformation($"SwaggerUI page was requested."); diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes/Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes.csproj b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes.csproj similarity index 89% rename from test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes/Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes.csproj rename to test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes.csproj index e24b463..a3dee7e 100644 --- a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes/Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes.csproj +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes.csproj @@ -9,7 +9,7 @@ - + diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes/FakeHttpTrigger.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes/FakeHttpTrigger.cs similarity index 94% rename from test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes/FakeHttpTrigger.cs rename to test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes/FakeHttpTrigger.cs index 4c72a04..0b09d00 100644 --- a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes/FakeHttpTrigger.cs +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes/FakeHttpTrigger.cs @@ -1,4 +1,4 @@ -#if NET461 +#if NET461 using System.Net; using System.Net.Http; #endif @@ -10,7 +10,7 @@ #endif using Microsoft.Azure.WebJobs; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes { /// /// This represents the fake class entity. diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes/FakeIntEnum.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes/FakeIntEnum.cs new file mode 100644 index 0000000..c6d56f5 --- /dev/null +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes/FakeIntEnum.cs @@ -0,0 +1,12 @@ +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes +{ + /// + /// This specifies fake enum values as int. + /// + public enum FakeIntEnum + { + IntValue1, + + IntValue2 + } +} diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes/FakeLongEnum.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes/FakeLongEnum.cs new file mode 100644 index 0000000..3890542 --- /dev/null +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes/FakeLongEnum.cs @@ -0,0 +1,12 @@ +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes +{ + /// + /// This specifies fake enum values as long. + /// + public enum FakeLongEnum : long + { + LongValue1, + + LongValue2 + } +} diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes/FakeModel.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes/FakeModel.cs similarity index 70% rename from test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes/FakeModel.cs rename to test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes/FakeModel.cs index d48ae34..eaff4eb 100644 --- a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes/FakeModel.cs +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes/FakeModel.cs @@ -1,6 +1,6 @@ -using Newtonsoft.Json; +using Newtonsoft.Json; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes { /// /// This represents the fake model entity. @@ -10,12 +10,13 @@ public class FakeModel /// /// Gets or sets the value. /// + [JsonRequired] public string FakeProperty { get; set; } /// /// Gets or sets the value 2. /// - [JsonProperty("anotherFakeProperty")] + [JsonProperty("anotherFakeProperty", Required = Required.Always)] public string FakeProperty2 { get; set; } /// @@ -29,9 +30,9 @@ public class FakeModel public FakeSubModel SubProperty { get; set; } /// - /// Gets or sets the value. + /// Gets or sets the value. /// - public FakeEnum EnumProperty { get; set; } + public FakeStringEnum EnumProperty { get; set; } } } diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes/FakeRecursiveModel.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes/FakeRecursiveModel.cs new file mode 100644 index 0000000..787fd4f --- /dev/null +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes/FakeRecursiveModel.cs @@ -0,0 +1,15 @@ +using Newtonsoft.Json; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes +{ + /// + /// This represents the recursive fake model entity + /// + public class FakeRecursiveModel + { + [JsonRequired] + public string StringValue { get; set; } + + public FakeRecursiveModel RecursiveValue { get; set; } + } +} diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes/FakeShortEnum.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes/FakeShortEnum.cs new file mode 100644 index 0000000..2a5fb0c --- /dev/null +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes/FakeShortEnum.cs @@ -0,0 +1,12 @@ +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes +{ + /// + /// This specifies fake enum values as short. + /// + public enum FakeShortEnum : short + { + ShortValue1, + + ShortValue2 + } +} diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes/FakeStringEnum.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes/FakeStringEnum.cs new file mode 100644 index 0000000..999b42c --- /dev/null +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes/FakeStringEnum.cs @@ -0,0 +1,20 @@ +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; + +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes +{ + /// + /// This specifies fake enum values as string. + /// + [JsonConverter(typeof(StringEnumConverter))] + public enum FakeStringEnum + { + [Display("lorem")] + StringValue1, + + [Display("ipsum")] + StringValue2 + } +} diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes/FakeSubModel.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes/FakeSubModel.cs similarity index 78% rename from test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes/FakeSubModel.cs rename to test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes/FakeSubModel.cs index fab9515..153e89e 100644 --- a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes/FakeSubModel.cs +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes/FakeSubModel.cs @@ -1,4 +1,4 @@ -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes { /// /// This represents the fake model entity. diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes/FakeTypeVisitor.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes/FakeTypeVisitor.cs new file mode 100644 index 0000000..e518767 --- /dev/null +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes/FakeTypeVisitor.cs @@ -0,0 +1,14 @@ +using System; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes +{ + public class FakeTypeVisitor : TypeVisitor + { + public bool IsTypeReferential(Type type) + { + return this.IsReferential(type); + } + } +} diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.csproj b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.csproj new file mode 100644 index 0000000..c5fe952 --- /dev/null +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.csproj @@ -0,0 +1,37 @@ + + + + net461;netcoreapp2.1;netcoreapp3.1 + + false + + + + + + + + + + + + + + + + + + + + + Always + + + Always + + + Always + + + + diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Attributes/DisplayAttributeTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Attributes/DisplayAttributeTests.cs similarity index 80% rename from test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Attributes/DisplayAttributeTests.cs rename to test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Attributes/DisplayAttributeTests.cs index d9cd75c..c160d28 100644 --- a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Attributes/DisplayAttributeTests.cs +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Attributes/DisplayAttributeTests.cs @@ -1,12 +1,12 @@ -using System; +using System; -using Aliencube.AzureFunctions.Extensions.OpenApi.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Attributes +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Attributes { [TestClass] public class DisplayAttributeTests diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Attributes/OpenApiOperationAttributeTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Attributes/OpenApiOperationAttributeTests.cs similarity index 86% rename from test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Attributes/OpenApiOperationAttributeTests.cs rename to test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Attributes/OpenApiOperationAttributeTests.cs index bc734df..add88e2 100644 --- a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Attributes/OpenApiOperationAttributeTests.cs +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Attributes/OpenApiOperationAttributeTests.cs @@ -1,13 +1,13 @@ -using System.Linq; +using System.Linq; -using Aliencube.AzureFunctions.Extensions.OpenApi.Attributes; -using Aliencube.AzureFunctions.Extensions.OpenApi.Enums; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums; using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Attributes +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Attributes { [TestClass] public class OpenApiOperationAttributeTests diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Attributes/OpenApiParameterAttributeTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Attributes/OpenApiParameterAttributeTests.cs similarity index 85% rename from test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Attributes/OpenApiParameterAttributeTests.cs rename to test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Attributes/OpenApiParameterAttributeTests.cs index 5664c9c..0698a1c 100644 --- a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Attributes/OpenApiParameterAttributeTests.cs +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Attributes/OpenApiParameterAttributeTests.cs @@ -1,14 +1,14 @@ using System; -using Aliencube.AzureFunctions.Extensions.OpenApi.Attributes; -using Aliencube.AzureFunctions.Extensions.OpenApi.Enums; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums; using FluentAssertions; using Microsoft.OpenApi.Models; using Microsoft.VisualStudio.TestTools.UnitTesting; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Attributes +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Attributes { [TestClass] public class OpenApiParameterAttributeTests diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Attributes/OpenApiRequestBodyAttributeTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Attributes/OpenApiRequestBodyAttributeTests.cs similarity index 88% rename from test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Attributes/OpenApiRequestBodyAttributeTests.cs rename to test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Attributes/OpenApiRequestBodyAttributeTests.cs index 70f5aa2..2622c51 100644 --- a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Attributes/OpenApiRequestBodyAttributeTests.cs +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Attributes/OpenApiRequestBodyAttributeTests.cs @@ -1,12 +1,12 @@ using System; -using Aliencube.AzureFunctions.Extensions.OpenApi.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Attributes +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Attributes { [TestClass] public class OpenApiRequestBodyAttributeTests diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Attributes/OpenApiResponseWithBodyAttributeTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Attributes/OpenApiResponseWithBodyAttributeTests.cs similarity index 90% rename from test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Attributes/OpenApiResponseWithBodyAttributeTests.cs rename to test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Attributes/OpenApiResponseWithBodyAttributeTests.cs index da4ee6e..6439517 100644 --- a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Attributes/OpenApiResponseWithBodyAttributeTests.cs +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Attributes/OpenApiResponseWithBodyAttributeTests.cs @@ -1,13 +1,13 @@ using System; using System.Net; -using Aliencube.AzureFunctions.Extensions.OpenApi.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Attributes +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Attributes { [TestClass] public class OpenApiResponseWithBodyAttributeTests diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Attributes/OpenApiResponseWithoutBodyAttributeTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Attributes/OpenApiResponseWithoutBodyAttributeTests.cs similarity index 78% rename from test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Attributes/OpenApiResponseWithoutBodyAttributeTests.cs rename to test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Attributes/OpenApiResponseWithoutBodyAttributeTests.cs index ebfde30..6051cdc 100644 --- a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Attributes/OpenApiResponseWithoutBodyAttributeTests.cs +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Attributes/OpenApiResponseWithoutBodyAttributeTests.cs @@ -1,12 +1,12 @@ -using System.Net; +using System.Net; -using Aliencube.AzureFunctions.Extensions.OpenApi.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Attributes +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Attributes { [TestClass] public class OpenApiResponseWithoutBodyAttributeTests diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Attributes/OpenApiSchemaVisibilityAttributeTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Attributes/OpenApiSchemaVisibilityAttributeTests.cs similarity index 77% rename from test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Attributes/OpenApiSchemaVisibilityAttributeTests.cs rename to test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Attributes/OpenApiSchemaVisibilityAttributeTests.cs index 5bfa58a..9181a6f 100644 --- a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Attributes/OpenApiSchemaVisibilityAttributeTests.cs +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Attributes/OpenApiSchemaVisibilityAttributeTests.cs @@ -1,13 +1,13 @@ -using System; +using System; -using Aliencube.AzureFunctions.Extensions.OpenApi.Attributes; -using Aliencube.AzureFunctions.Extensions.OpenApi.Enums; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums; using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Attributes +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Attributes { [TestClass] public class OpenApiSchemaVisibilityAttributeTests diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Configurations/ExtensionsSettingsTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Configurations/ExtensionsSettingsTests.cs similarity index 70% rename from test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Configurations/ExtensionsSettingsTests.cs rename to test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Configurations/ExtensionsSettingsTests.cs index d889f78..05d19c0 100644 --- a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Configurations/ExtensionsSettingsTests.cs +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Configurations/ExtensionsSettingsTests.cs @@ -1,10 +1,10 @@ -using Aliencube.AzureFunctions.Extensions.OpenApi.Configurations; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Configurations; using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Configurations +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Configurations { [TestClass] public class ExtensionsSettingsTests diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Configurations/HostJsonSettingsTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Configurations/HostJsonSettingsTests.cs similarity index 75% rename from test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Configurations/HostJsonSettingsTests.cs rename to test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Configurations/HostJsonSettingsTests.cs index 82154cc..b68c130 100644 --- a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Configurations/HostJsonSettingsTests.cs +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Configurations/HostJsonSettingsTests.cs @@ -1,10 +1,10 @@ -using Aliencube.AzureFunctions.Extensions.OpenApi.Configurations; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Configurations; using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Configurations +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Configurations { [TestClass] public class HostJsonSettingsTests diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Configurations/HttpSettingsTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Configurations/HttpSettingsTests.cs similarity index 70% rename from test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Configurations/HttpSettingsTests.cs rename to test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Configurations/HttpSettingsTests.cs index 0ee4730..bc2d13f 100644 --- a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Configurations/HttpSettingsTests.cs +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Configurations/HttpSettingsTests.cs @@ -1,10 +1,10 @@ -using Aliencube.AzureFunctions.Extensions.OpenApi.Configurations; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Configurations; using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Configurations +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Configurations { [TestClass] public class HttpSettingsTests diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/DocumentHelperTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/DocumentHelperTests.cs new file mode 100644 index 0000000..a7f349e --- /dev/null +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/DocumentHelperTests.cs @@ -0,0 +1,26 @@ +using System; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Configurations; + +using FluentAssertions; + +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests +{ + [TestClass] + public class DocumentHelperTests + { + [TestMethod] + public void Given_Null_Constructor_Should_Throw_Exception() + { + Action action = () => new DocumentHelper(null, null); + action.Should().Throw(); + + var filter = new RouteConstraintFilter(); + + action = () => new DocumentHelper(filter, null); + action.Should().Throw(); + } + } +} diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/DocumentTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/DocumentTests.cs similarity index 73% rename from test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/DocumentTests.cs rename to test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/DocumentTests.cs index ba335e5..4af1c41 100644 --- a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/DocumentTests.cs +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/DocumentTests.cs @@ -1,16 +1,21 @@ using System; + #if NET461 using System.Net.Http; #endif + +using System.Reflection; using System.Threading.Tasks; -using Aliencube.AzureFunctions.Extensions.OpenApi.Abstractions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors; using FluentAssertions; #if !NET461 using Microsoft.AspNetCore.Http; #endif + using Microsoft.OpenApi; using Microsoft.OpenApi.Models; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -18,8 +23,9 @@ using Moq; using Newtonsoft.Json.Linq; +using Newtonsoft.Json.Serialization; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Tests +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests { [TestClass] public class DocumentTests @@ -32,6 +38,47 @@ public void Given_Null_Constructor_Should_Throw_Exception() action.Should().Throw(); } + [TestMethod] + public void Given_That_When_InitialiseDocument_Invoked_Then_It_Should_Return_Result() + { + var field = typeof(Document).GetField("_document", BindingFlags.Instance | BindingFlags.NonPublic); + var helper = new Mock(); + var doc = new Document(helper.Object); + + var result = doc.InitialiseDocument(); + + field.GetValue(result).Should().NotBeNull(); + field.GetValue(result).Should().BeOfType(); + } + + [TestMethod] + public void Given_That_When_AddNamingStrategy_Invoked_Then_It_Should_Return_Result() + { + var field = typeof(Document).GetField("_strategy", BindingFlags.Instance | BindingFlags.NonPublic); + var strategy = new DefaultNamingStrategy(); + var helper = new Mock(); + var doc = new Document(helper.Object); + + var result = doc.AddNamingStrategy(strategy); + + field.GetValue(result).Should().NotBeNull(); + field.GetValue(result).Should().BeOfType(); + } + + [TestMethod] + public void Given_That_When_AddVisitors_Invoked_Then_It_Should_Return_Result() + { + var field = typeof(Document).GetField("_collection", BindingFlags.Instance | BindingFlags.NonPublic); + var collection = new VisitorCollection(); + var helper = new Mock(); + var doc = new Document(helper.Object); + + var result = doc.AddVisitors(collection); + + field.GetValue(result).Should().NotBeNull(); + field.GetValue(result).Should().BeOfType(); + } + [TestMethod] public async Task Given_VersionAndFormat_RenderAsync_Should_Return_Result() { diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Enums/OpenApiFormatTypeTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Enums/OpenApiFormatTypeTests.cs similarity index 84% rename from test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Enums/OpenApiFormatTypeTests.cs rename to test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Enums/OpenApiFormatTypeTests.cs index 2abbaeb..4b9b77d 100644 --- a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Enums/OpenApiFormatTypeTests.cs +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Enums/OpenApiFormatTypeTests.cs @@ -1,14 +1,14 @@ using System.Linq; using System.Reflection; -using Aliencube.AzureFunctions.Extensions.OpenApi.Attributes; -using Aliencube.AzureFunctions.Extensions.OpenApi.Enums; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums; using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Enums +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Enums { [TestClass] public class OpenApiFormatTypeTests diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Enums/OpenApiParameterCollectionDelimiterTypeTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Enums/OpenApiParameterCollectionDelimiterTypeTests.cs similarity index 85% rename from test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Enums/OpenApiParameterCollectionDelimiterTypeTests.cs rename to test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Enums/OpenApiParameterCollectionDelimiterTypeTests.cs index a0e61e8..a1614d9 100644 --- a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Enums/OpenApiParameterCollectionDelimiterTypeTests.cs +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Enums/OpenApiParameterCollectionDelimiterTypeTests.cs @@ -1,14 +1,14 @@ -using System.Linq; +using System.Linq; using System.Reflection; -using Aliencube.AzureFunctions.Extensions.OpenApi.Attributes; -using Aliencube.AzureFunctions.Extensions.OpenApi.Enums; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums; using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Enums +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Enums { [TestClass] public class OpenApiParameterCollectionDelimiterTypeTests diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Enums/OpenApiVersionTypeTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Enums/OpenApiVersionTypeTests.cs similarity index 83% rename from test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Enums/OpenApiVersionTypeTests.cs rename to test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Enums/OpenApiVersionTypeTests.cs index f25750b..1559971 100644 --- a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Enums/OpenApiVersionTypeTests.cs +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Enums/OpenApiVersionTypeTests.cs @@ -1,14 +1,14 @@ -using System.Linq; +using System.Linq; using System.Reflection; -using Aliencube.AzureFunctions.Extensions.OpenApi.Attributes; -using Aliencube.AzureFunctions.Extensions.OpenApi.Enums; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums; using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Enums +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Enums { [TestClass] public class OpenApiVersionTypeTests diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Enums/OpenApiVisibilityTypeTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Enums/OpenApiVisibilityTypeTests.cs similarity index 88% rename from test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Enums/OpenApiVisibilityTypeTests.cs rename to test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Enums/OpenApiVisibilityTypeTests.cs index 08e3c47..6bb9125 100644 --- a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Enums/OpenApiVisibilityTypeTests.cs +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Enums/OpenApiVisibilityTypeTests.cs @@ -1,14 +1,14 @@ -using System.Linq; +using System.Linq; using System.Reflection; -using Aliencube.AzureFunctions.Extensions.OpenApi.Attributes; -using Aliencube.AzureFunctions.Extensions.OpenApi.Enums; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums; using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Enums +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Enums { [TestClass] public class OpenApiVisibilityTypeTests diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Extensions/EnumExtensionsTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Extensions/EnumExtensionsTests.cs new file mode 100644 index 0000000..c91cb41 --- /dev/null +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Extensions/EnumExtensionsTests.cs @@ -0,0 +1,109 @@ +using System; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes; + +using FluentAssertions; + +using Microsoft.OpenApi; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Extensions +{ + [TestClass] + public class EnumExtensionsTests + { + [DataTestMethod] + [DataRow(FakeStringEnum.StringValue1, "lorem")] + [DataRow(FakeStringEnum.StringValue2, "ipsum")] + public void Given_Enum_Method_Should_Return_Value(FakeStringEnum @enum, string expected) + { + var name = EnumExtensions.ToDisplayName(@enum); + + name.Should().Be(expected); + } + + [TestMethod] + public void Given_TypeCode_ToDataType_Should_Throw_Exception() + { + Action action = () => EnumExtensions.ToDataType(null); + action.Should().Throw(); + } + + [DataTestMethod] + [DataRow(typeof(short), "integer")] + [DataRow(typeof(int), "integer")] + [DataRow(typeof(long), "integer")] + [DataRow(typeof(float), "number")] + [DataRow(typeof(double), "number")] + [DataRow(typeof(decimal), "number")] + [DataRow(typeof(bool), "boolean")] + [DataRow(typeof(DateTime), "string")] + [DataRow(typeof(DateTimeOffset), "string")] + [DataRow(typeof(Guid), "string")] + [DataRow(typeof(object), "object")] + public void Given_TypeCode_ToDataType_Should_Return_Value(Type type, string expected) + { + var dataType = EnumExtensions.ToDataType(type); + + dataType.Should().Be(expected); + } + + [TestMethod] + public void Given_TypeCode_ToDataFormat_Should_Throw_Exception() + { + Action action = () => EnumExtensions.ToDataFormat(null); + action.Should().Throw(); + } + + [DataTestMethod] + [DataRow(typeof(short), "int32")] + [DataRow(typeof(int), "int32")] + [DataRow(typeof(long), "int64")] + [DataRow(typeof(float), "float")] + [DataRow(typeof(double), "double")] + [DataRow(typeof(decimal), "double")] + [DataRow(typeof(bool), null)] + [DataRow(typeof(DateTime), "date-time")] + [DataRow(typeof(DateTimeOffset), "date-time")] + [DataRow(typeof(Guid), "uuid")] + [DataRow(typeof(object), null)] + public void Given_TypeCode_ToDataFormat_Should_Return_Value(Type type, string expected) + { + var dataType = EnumExtensions.ToDataFormat(type); + + dataType.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(OpenApiFormat.Json, "application/json")] + [DataRow(OpenApiFormat.Yaml, "application/yaml")] + public void Given_OpenApiFormat_When_GetContentType_Invoked_Then_It_Should_Return_Result(OpenApiFormat format, string expected) + { + var result = EnumExtensions.GetContentType(format); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(OpenApiVersionType.V2, OpenApiSpecVersion.OpenApi2_0)] + [DataRow(OpenApiVersionType.V3, OpenApiSpecVersion.OpenApi3_0)] + public void Given_OpenApiVersionType_When_ToOpenApiSpecVersion_Invoked_Then_It_Should_Return_Result(OpenApiVersionType version, OpenApiSpecVersion expected) + { + var result = EnumExtensions.ToOpenApiSpecVersion(version); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(OpenApiFormatType.Json, OpenApiFormat.Json)] + [DataRow(OpenApiFormatType.Yaml, OpenApiFormat.Yaml)] + public void Given_OpenApiFormatType_When_ToOpenApiFormat_Invoked_Then_It_Should_Return_Result(OpenApiFormatType format, OpenApiFormat expected) + { + var result = EnumExtensions.ToOpenApiFormat(format); + + result.Should().Be(expected); + } + } +} diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Extensions/MemberInfoExtensionsTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Extensions/MemberInfoExtensionsTests.cs similarity index 87% rename from test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Extensions/MemberInfoExtensionsTests.cs rename to test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Extensions/MemberInfoExtensionsTests.cs index d6f3bd7..ce68f49 100644 --- a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Extensions/MemberInfoExtensionsTests.cs +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Extensions/MemberInfoExtensionsTests.cs @@ -1,38 +1,38 @@ -using System; -using System.Linq; -using System.Reflection; - -using Aliencube.AzureFunctions.Extensions.DependencyInjection.Tests.Fakes; - -using FluentAssertions; - -using Microsoft.VisualStudio.TestTools.UnitTesting; - -using MemberInfoExtensions = Aliencube.AzureFunctions.Extensions.OpenApi.Extensions.MemberInfoExtensions; - -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Extensions -{ - [TestClass] - public class MemberInfoExtensionsTests - { - [TestMethod] - public void Given_Null_When_ExistsCustomAttribute_Invoked_Then_It_Should_Throw_Exception() - { - Action action = () => MemberInfoExtensions.ExistsCustomAttribute(null); - - action.Should().Throw(); - } - - [DataTestMethod] - [DataRow("DoSomething", true)] - [DataRow("DoOtherThing", false)] - public void Given_MemberInfo_When_ExistsCustomAttribute_Invoked_Then_It_Should_Return_Result(string methodName, bool expected) - { - var member = typeof(FakeClass).GetMember(methodName, BindingFlags.Public | BindingFlags.Instance).First(); - - var result = MemberInfoExtensions.ExistsCustomAttribute(member); - - result.Should().Be(expected); - } - } -} +using System; +using System.Linq; +using System.Reflection; + +using Aliencube.AzureFunctions.Extensions.DependencyInjection.Tests.Fakes; + +using FluentAssertions; + +using Microsoft.VisualStudio.TestTools.UnitTesting; + +using MemberInfoExtensions = Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions.MemberInfoExtensions; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Extensions +{ + [TestClass] + public class MemberInfoExtensionsTests + { + [TestMethod] + public void Given_Null_When_ExistsCustomAttribute_Invoked_Then_It_Should_Throw_Exception() + { + Action action = () => MemberInfoExtensions.ExistsCustomAttribute(null); + + action.Should().Throw(); + } + + [DataTestMethod] + [DataRow("DoSomething", true)] + [DataRow("DoOtherThing", false)] + public void Given_MemberInfo_When_ExistsCustomAttribute_Invoked_Then_It_Should_Return_Result(string methodName, bool expected) + { + var member = typeof(FakeClass).GetMember(methodName, BindingFlags.Public | BindingFlags.Instance).First(); + + var result = MemberInfoExtensions.ExistsCustomAttribute(member); + + result.Should().Be(expected); + } + } +} diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Extensions/MethodInfoExtensionsTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Extensions/MethodInfoExtensionsTests.cs similarity index 89% rename from test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Extensions/MethodInfoExtensionsTests.cs rename to test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Extensions/MethodInfoExtensionsTests.cs index 4e980b2..9ce39eb 100644 --- a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Extensions/MethodInfoExtensionsTests.cs +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Extensions/MethodInfoExtensionsTests.cs @@ -1,46 +1,46 @@ -using System; -using System.Reflection; - -using Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes; - -using FluentAssertions; - -using Microsoft.Azure.WebJobs; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -using MethodInfoExtensions = Aliencube.AzureFunctions.Extensions.OpenApi.Extensions.MethodInfoExtensions; - -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Extensions -{ - [TestClass] - public class MethodInfoExtensionsTests - { - [TestMethod] - public void Given_Null_When_GetFunctionName_Invoked_Then_It_Should_Throw_Exception() - { - Action action = () => MethodInfoExtensions.GetFunctionName(null); - - action.Should().Throw(); - } - - [DataTestMethod] - [DataRow("DoSomething", "FakeFunction")] - public void Given_MemberInfo_When_ExistsCustomAttribute_Invoked_Then_It_Should_Return_Result(string methodName, string expected) - { - var method = typeof(FakeHttpTrigger).GetMethod(methodName, BindingFlags.Public | BindingFlags.Instance); - - var result = MethodInfoExtensions.GetFunctionName(method); - - result.Should().BeOfType(); - result.Name.Should().Be(expected); - } - - [TestMethod] - public void Given_Null_When_GetHttpTrigger_Invoked_Then_It_Should_Throw_Exception() - { - Action action = () => MethodInfoExtensions.GetHttpTrigger(null); - - action.Should().Throw(); - } - } -} +using System; +using System.Reflection; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes; + +using FluentAssertions; + +using Microsoft.Azure.WebJobs; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +using MethodInfoExtensions = Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions.MethodInfoExtensions; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Extensions +{ + [TestClass] + public class MethodInfoExtensionsTests + { + [TestMethod] + public void Given_Null_When_GetFunctionName_Invoked_Then_It_Should_Throw_Exception() + { + Action action = () => MethodInfoExtensions.GetFunctionName(null); + + action.Should().Throw(); + } + + [DataTestMethod] + [DataRow("DoSomething", "FakeFunction")] + public void Given_MemberInfo_When_ExistsCustomAttribute_Invoked_Then_It_Should_Return_Result(string methodName, string expected) + { + var method = typeof(FakeHttpTrigger).GetMethod(methodName, BindingFlags.Public | BindingFlags.Instance); + + var result = MethodInfoExtensions.GetFunctionName(method); + + result.Should().BeOfType(); + result.Name.Should().Be(expected); + } + + [TestMethod] + public void Given_Null_When_GetHttpTrigger_Invoked_Then_It_Should_Throw_Exception() + { + Action action = () => MethodInfoExtensions.GetHttpTrigger(null); + + action.Should().Throw(); + } + } +} diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Extensions/OpenApiInfoExtensionsTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Extensions/OpenApiInfoExtensionsTests.cs similarity index 89% rename from test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Extensions/OpenApiInfoExtensionsTests.cs rename to test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Extensions/OpenApiInfoExtensionsTests.cs index 8ead0f9..af3346d 100644 --- a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Extensions/OpenApiInfoExtensionsTests.cs +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Extensions/OpenApiInfoExtensionsTests.cs @@ -1,13 +1,13 @@ -using System; +using System; -using Aliencube.AzureFunctions.Extensions.OpenApi.Extensions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; using FluentAssertions; using Microsoft.OpenApi.Models; using Microsoft.VisualStudio.TestTools.UnitTesting; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Extensions +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Extensions { [TestClass] public class OpenApiInfoExtensionsTests diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Extensions/OpenApiParameterAttributeExtensionsTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Extensions/OpenApiParameterAttributeExtensionsTests.cs similarity index 90% rename from test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Extensions/OpenApiParameterAttributeExtensionsTests.cs rename to test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Extensions/OpenApiParameterAttributeExtensionsTests.cs index 5183cfe..d93bf07 100644 --- a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Extensions/OpenApiParameterAttributeExtensionsTests.cs +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Extensions/OpenApiParameterAttributeExtensionsTests.cs @@ -2,10 +2,10 @@ using System.Collections.Generic; using System.Linq; -using Aliencube.AzureFunctions.Extensions.OpenApi.Attributes; -using Aliencube.AzureFunctions.Extensions.OpenApi.Enums; -using Aliencube.AzureFunctions.Extensions.OpenApi.Extensions; -using Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes; using FluentAssertions; @@ -15,7 +15,7 @@ using Newtonsoft.Json.Serialization; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Extensions +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Extensions { [TestClass] public class OpenApiParameterAttributeExtensionsTests @@ -102,10 +102,10 @@ public void Given_Value_With_Long_Type_When_ToOpenApiParameter_Invoked_Then_It_S public void Given_Value_With_Enum_Type_When_ToOpenApiParameter_Invoked_Then_It_Should_Return_Result() { var strategy = new CamelCaseNamingStrategy(); - var names = typeof(FakeEnum).ToOpenApiStringCollection(strategy).Select(p => (p as OpenApiString).Value).ToList(); + var names = typeof(FakeStringEnum).ToOpenApiStringCollection(strategy).Select(p => (p as OpenApiString).Value).ToList(); var attribute = new OpenApiParameterAttribute("hello") { - Type = typeof(FakeEnum), + Type = typeof(FakeStringEnum), Description = "hello world", Required = true, In = ParameterLocation.Query @@ -127,10 +127,10 @@ public void Given_Value_With_Enum_Type_When_ToOpenApiParameter_Invoked_Then_It_S public void Given_Value_With_List_Enum_Type_When_ToOpenApiParameter_Invoked_Then_It_Should_Return_Result() { var strategy = new CamelCaseNamingStrategy(); - var names = typeof(FakeEnum).ToOpenApiStringCollection(strategy).Select(p => (p as OpenApiString).Value).ToList(); + var names = typeof(FakeStringEnum).ToOpenApiStringCollection(strategy).Select(p => (p as OpenApiString).Value).ToList(); var attribute = new OpenApiParameterAttribute("hello") { - Type = typeof(List), + Type = typeof(List), Description = "hello world", Required = true, In = ParameterLocation.Query diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Extensions/PropertyInfoExtensionsTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Extensions/PropertyInfoExtensionsTests.cs similarity index 72% rename from test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Extensions/PropertyInfoExtensionsTests.cs rename to test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Extensions/PropertyInfoExtensionsTests.cs index f459651..20d7abc 100644 --- a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Extensions/PropertyInfoExtensionsTests.cs +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Extensions/PropertyInfoExtensionsTests.cs @@ -1,40 +1,44 @@ -using System.Reflection; - -using Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes; - -using FluentAssertions; - -using Microsoft.VisualStudio.TestTools.UnitTesting; - -using PropertyInfoExtensions = Aliencube.AzureFunctions.Extensions.OpenApi.Extensions.PropertyInfoExtensions; - -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Extensions -{ - [TestClass] - public class PropertyInfoExtensionsTests - { - [TestMethod] - public void Given_Property_When_GetJsonPropertyName_Invoked_Then_It_Should_Return_PropertyName() - { - var name = "FakeProperty"; - var jsonPropertyName = "FakeProperty"; - var property = typeof(FakeModel).GetProperty(name, BindingFlags.Public | BindingFlags.Instance); - - var result = PropertyInfoExtensions.GetJsonPropertyName(property); - - result.Should().Be(jsonPropertyName); - } - - [TestMethod] - public void Given_Property_When_GetJsonPropertyName_Invoked_Then_It_Should_Return_JsonPropertyName() - { - var name = "FakeProperty2"; - var jsonPropertyName = "anotherFakeProperty"; - var property = typeof(FakeModel).GetProperty(name, BindingFlags.Public | BindingFlags.Instance); - - var result = PropertyInfoExtensions.GetJsonPropertyName(property); - - result.Should().Be(jsonPropertyName); - } - } -} \ No newline at end of file +using System.Reflection; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes; + +using FluentAssertions; + +using Microsoft.VisualStudio.TestTools.UnitTesting; + +using Newtonsoft.Json.Serialization; + +using PropertyInfoExtensions = Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions.PropertyInfoExtensions; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Extensions +{ + [TestClass] + public class PropertyInfoExtensionsTests + { + [TestMethod] + public void Given_Property_When_GetJsonPropertyName_Invoked_Then_It_Should_Return_PropertyName() + { + var name = "FakeProperty"; + var jsonPropertyName = "FakeProperty"; + var property = typeof(FakeModel).GetProperty(name, BindingFlags.Public | BindingFlags.Instance); + var namingStrategy = new DefaultNamingStrategy(); + + var result = PropertyInfoExtensions.GetJsonPropertyName(property, namingStrategy); + + result.Should().Be(jsonPropertyName); + } + + [TestMethod] + public void Given_Property_When_GetJsonPropertyName_Invoked_Then_It_Should_Return_JsonPropertyName() + { + var name = "FakeProperty2"; + var jsonPropertyName = "anotherFakeProperty"; + var property = typeof(FakeModel).GetProperty(name, BindingFlags.Public | BindingFlags.Instance); + var namingStrategy = new DefaultNamingStrategy(); + + var result = PropertyInfoExtensions.GetJsonPropertyName(property, namingStrategy); + + result.Should().Be(jsonPropertyName); + } + } +} diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Extensions/SwaggerUIExtensionsTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Extensions/SwaggerUIExtensionsTests.cs similarity index 85% rename from test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Extensions/SwaggerUIExtensionsTests.cs rename to test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Extensions/SwaggerUIExtensionsTests.cs index b678c6c..ba8d0f8 100644 --- a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Extensions/SwaggerUIExtensionsTests.cs +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Extensions/SwaggerUIExtensionsTests.cs @@ -1,8 +1,8 @@ -using System; +using System; using System.Threading.Tasks; -using Aliencube.AzureFunctions.Extensions.OpenApi.Abstractions; -using Aliencube.AzureFunctions.Extensions.OpenApi.Extensions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; using FluentAssertions; @@ -10,7 +10,7 @@ using Moq; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Extensions +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Extensions { [TestClass] public class SwaggerUIExtensionsTests diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Extensions/TypeExtensionsTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Extensions/TypeExtensionsTests.cs new file mode 100644 index 0000000..3035e61 --- /dev/null +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Extensions/TypeExtensionsTests.cs @@ -0,0 +1,61 @@ +using System.Collections.Generic; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; + +using FluentAssertions; + +using Microsoft.VisualStudio.TestTools.UnitTesting; + +using Newtonsoft.Json.Linq; +using Newtonsoft.Json.Serialization; + +using TypeExtensions = Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions.TypeExtensions; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Extensions +{ + [TestClass] + public class TypeExtensionsTests + { + [TestMethod] + public void Given_IList_Should_Return_True() => + typeof(IList).IsOpenApiArray().Should().BeTrue(); + + [TestMethod] + public void Given_List_Should_Return_True() => + typeof(List).IsOpenApiArray().Should().BeTrue(); + + [TestMethod] + public void Given_Array_Method_Should_Return_True() => + typeof(string[]).IsOpenApiArray().Should().BeTrue(); + + [TestMethod] + public void Given_Object_That_Extends_List_Should_Return_False() => + typeof(JObject).IsOpenApiArray().Should().BeFalse(); + + [TestMethod] + public void Given_String_Method_Should_Return_False() => + typeof(string).IsOpenApiArray().Should().BeFalse(); + + [TestMethod] + public void Given_DefaultNamingStrategy_When_GetOpenApiTypeName_Invoked_Then_It_Should_Return_Result() + { + var type = typeof(int); + var strategy = new DefaultNamingStrategy(); + + var result = TypeExtensions.GetOpenApiTypeName(type, strategy); + + result.Should().Be("Int32"); + } + + [TestMethod] + public void Given_CamelCaseNamingStrategy_When_GetOpenApiTypeName_Invoked_Then_It_Should_Return_Result() + { + var type = typeof(int); + var strategy = new CamelCaseNamingStrategy(); + + var result = TypeExtensions.GetOpenApiTypeName(type, strategy); + + result.Should().Be("int32"); + } + } +} diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Resolvers/HostJsonResolverTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Resolvers/HostJsonResolverTests.cs similarity index 88% rename from test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Resolvers/HostJsonResolverTests.cs rename to test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Resolvers/HostJsonResolverTests.cs index 313a4a3..cef1cc4 100644 --- a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Resolvers/HostJsonResolverTests.cs +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Resolvers/HostJsonResolverTests.cs @@ -1,6 +1,6 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; +using Microsoft.VisualStudio.TestTools.UnitTesting; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Resolvers +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Resolvers { [TestClass] public class HostJsonResolverTests diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Resolvers/OpenApiInfoResolverTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Resolvers/OpenApiInfoResolverTests.cs similarity index 79% rename from test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Resolvers/OpenApiInfoResolverTests.cs rename to test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Resolvers/OpenApiInfoResolverTests.cs index ed4f999..3cb832d 100644 --- a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Resolvers/OpenApiInfoResolverTests.cs +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Resolvers/OpenApiInfoResolverTests.cs @@ -1,4 +1,4 @@ -using Aliencube.AzureFunctions.Extensions.OpenApi.Resolvers; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Resolvers; using FluentAssertions; @@ -6,7 +6,7 @@ using Microsoft.OpenApi.Models; using Microsoft.VisualStudio.TestTools.UnitTesting; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Resolvers +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Resolvers { [TestClass] public class OpenApiInfoResolverTests diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Resolvers/OpenApiSettingsJsonResolverTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Resolvers/OpenApiSettingsJsonResolverTests.cs similarity index 84% rename from test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Resolvers/OpenApiSettingsJsonResolverTests.cs rename to test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Resolvers/OpenApiSettingsJsonResolverTests.cs index 24fb57d..e377736 100644 --- a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Resolvers/OpenApiSettingsJsonResolverTests.cs +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Resolvers/OpenApiSettingsJsonResolverTests.cs @@ -1,4 +1,4 @@ -using Aliencube.AzureFunctions.Extensions.OpenApi.Resolvers; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Resolvers; using FluentAssertions; @@ -7,7 +7,7 @@ using Moq; -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Resolvers +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Resolvers { [TestClass] public class OpenApiSettingsJsonResolverTests diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/BooleanTypeVisitorTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/BooleanTypeVisitorTests.cs new file mode 100644 index 0000000..74648e4 --- /dev/null +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/BooleanTypeVisitorTests.cs @@ -0,0 +1,124 @@ +using System; +using System.Collections.Generic; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors; + +using FluentAssertions; + +using Microsoft.OpenApi.Any; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +using Newtonsoft.Json.Serialization; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Visitors +{ + [TestClass] + public class BooleanTypeVisitorTests + { + private IVisitor _visitor; + private NamingStrategy _strategy; + + [TestInitialize] + public void Init() + { + this._visitor = new BooleanTypeVisitor(); + this._strategy = new CamelCaseNamingStrategy(); + } + + [DataTestMethod] + [DataRow(typeof(bool), false)] + public void Given_Type_When_IsNavigatable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsNavigatable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(bool), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(bool), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsParameterVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsParameterVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(bool), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsPayloadVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsPayloadVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow("boolean", null)] + public void Given_Type_When_Visit_Invoked_Then_It_Should_Return_Result(string dataType, string dataFormat) + { + var name = "hello"; + var acceptor = new OpenApiSchemaAcceptor(); + var type = new KeyValuePair(name, typeof(bool)); + + this._visitor.Visit(acceptor, type, this._strategy); + + acceptor.Schemas.Should().ContainKey(name); + acceptor.Schemas[name].Type.Should().Be(dataType); + acceptor.Schemas[name].Format.Should().Be(dataFormat); + } + + [DataTestMethod] + [DataRow(OpenApiVisibilityType.Advanced)] + [DataRow(OpenApiVisibilityType.Important)] + [DataRow(OpenApiVisibilityType.Internal)] + public void Given_Attribute_When_Visit_Invoked_Then_It_Should_Return_Result(OpenApiVisibilityType visibility) + { + var name = "hello"; + var acceptor = new OpenApiSchemaAcceptor(); + var type = new KeyValuePair(name, typeof(bool)); + var attribute = new OpenApiSchemaVisibilityAttribute(visibility); + + this._visitor.Visit(acceptor, type, this._strategy, attribute); + + acceptor.Schemas[name].Extensions.Should().ContainKey("x-ms-visibility"); + acceptor.Schemas[name].Extensions["x-ms-visibility"].Should().BeOfType(); + (acceptor.Schemas[name].Extensions["x-ms-visibility"] as OpenApiString).Value.Should().Be(visibility.ToDisplayName(this._strategy)); + } + + [DataTestMethod] + [DataRow("boolean", null)] + public void Given_Type_When_ParameterVisit_Invoked_Then_It_Should_Return_Result(string dataType, string dataFormat) + { + var result = this._visitor.ParameterVisit(typeof(bool), this._strategy); + + result.Type.Should().Be(dataType); + result.Format.Should().Be(dataFormat); + } + + [DataTestMethod] + [DataRow("boolean", null)] + public void Given_Type_When_PayloadVisit_Invoked_Then_It_Should_Return_Result(string dataType, string dataFormat) + { + var result = this._visitor.PayloadVisit(typeof(bool), this._strategy); + + result.Type.Should().Be(dataType); + result.Format.Should().Be(dataFormat); + } + } +} diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/DateTimeOffsetObjectTypeVisitorTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/DateTimeOffsetObjectTypeVisitorTests.cs new file mode 100644 index 0000000..a8f2a06 --- /dev/null +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/DateTimeOffsetObjectTypeVisitorTests.cs @@ -0,0 +1,124 @@ +using System; +using System.Collections.Generic; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors; + +using FluentAssertions; + +using Microsoft.OpenApi.Any; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +using Newtonsoft.Json.Serialization; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Visitors +{ + [TestClass] + public class DateTimeOffsetObjectTypeVisitorTests + { + private IVisitor _visitor; + private NamingStrategy _strategy; + + [TestInitialize] + public void Init() + { + this._visitor = new DateTimeOffsetObjectTypeVisitor(); + this._strategy = new CamelCaseNamingStrategy(); + } + + [DataTestMethod] + [DataRow(typeof(DateTimeOffset), false)] + public void Given_Type_When_IsNavigatable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsNavigatable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(DateTimeOffset), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(DateTimeOffset), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsParameterVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsParameterVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(DateTimeOffset), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsPayloadVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsPayloadVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow("string", "date-time")] + public void Given_Type_When_Visit_Invoked_Then_It_Should_Return_Result(string dataType, string dataFormat) + { + var name = "hello"; + var acceptor = new OpenApiSchemaAcceptor(); + var type = new KeyValuePair(name, typeof(DateTimeOffset)); + + this._visitor.Visit(acceptor, type, this._strategy); + + acceptor.Schemas.Should().ContainKey(name); + acceptor.Schemas[name].Type.Should().Be(dataType); + acceptor.Schemas[name].Format.Should().Be(dataFormat); + } + + [DataTestMethod] + [DataRow(OpenApiVisibilityType.Advanced)] + [DataRow(OpenApiVisibilityType.Important)] + [DataRow(OpenApiVisibilityType.Internal)] + public void Given_Attribute_When_Visit_Invoked_Then_It_Should_Return_Result(OpenApiVisibilityType visibility) + { + var name = "hello"; + var acceptor = new OpenApiSchemaAcceptor(); + var type = new KeyValuePair(name, typeof(DateTimeOffset)); + var attribute = new OpenApiSchemaVisibilityAttribute(visibility); + + this._visitor.Visit(acceptor, type, this._strategy, attribute); + + acceptor.Schemas[name].Extensions.Should().ContainKey("x-ms-visibility"); + acceptor.Schemas[name].Extensions["x-ms-visibility"].Should().BeOfType(); + (acceptor.Schemas[name].Extensions["x-ms-visibility"] as OpenApiString).Value.Should().Be(visibility.ToDisplayName(this._strategy)); + } + + [DataTestMethod] + [DataRow("string", "date-time")] + public void Given_Type_When_ParameterVisit_Invoked_Then_It_Should_Return_Result(string dataType, string dataFormat) + { + var result = this._visitor.ParameterVisit(typeof(DateTimeOffset), this._strategy); + + result.Type.Should().Be(dataType); + result.Format.Should().Be(dataFormat); + } + + [DataTestMethod] + [DataRow("string", "date-time")] + public void Given_Type_When_PayloadVisit_Invoked_Then_It_Should_Return_Null(string dataType, string dataFormat) + { + var result = this._visitor.PayloadVisit(typeof(DateTimeOffset), this._strategy); + + result.Type.Should().Be(dataType); + result.Format.Should().Be(dataFormat); + } + } +} diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/DateTimeTypeVisitorTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/DateTimeTypeVisitorTests.cs new file mode 100644 index 0000000..c11c058 --- /dev/null +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/DateTimeTypeVisitorTests.cs @@ -0,0 +1,124 @@ +using System; +using System.Collections.Generic; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors; + +using FluentAssertions; + +using Microsoft.OpenApi.Any; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +using Newtonsoft.Json.Serialization; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Visitors +{ + [TestClass] + public class DateTimeTypeVisitorTests + { + private IVisitor _visitor; + private NamingStrategy _strategy; + + [TestInitialize] + public void Init() + { + this._visitor = new DateTimeTypeVisitor(); + this._strategy = new CamelCaseNamingStrategy(); + } + + [DataTestMethod] + [DataRow(typeof(DateTimeOffset), false)] + public void Given_Type_When_IsNavigatable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsNavigatable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(DateTime), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(DateTime), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsParameterVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsParameterVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(DateTime), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsPayloadVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsPayloadVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow("string", "date-time")] + public void Given_Type_When_Visit_Invoked_Then_It_Should_Return_Result(string dataType, string dataFormat) + { + var name = "hello"; + var acceptor = new OpenApiSchemaAcceptor(); + var type = new KeyValuePair(name, typeof(DateTime)); + + this._visitor.Visit(acceptor, type, this._strategy); + + acceptor.Schemas.Should().ContainKey(name); + acceptor.Schemas[name].Type.Should().Be(dataType); + acceptor.Schemas[name].Format.Should().Be(dataFormat); + } + + [DataTestMethod] + [DataRow(OpenApiVisibilityType.Advanced)] + [DataRow(OpenApiVisibilityType.Important)] + [DataRow(OpenApiVisibilityType.Internal)] + public void Given_Attribute_When_Visit_Invoked_Then_It_Should_Return_Result(OpenApiVisibilityType visibility) + { + var name = "hello"; + var acceptor = new OpenApiSchemaAcceptor(); + var type = new KeyValuePair(name, typeof(DateTime)); + var attribute = new OpenApiSchemaVisibilityAttribute(visibility); + + this._visitor.Visit(acceptor, type, this._strategy, attribute); + + acceptor.Schemas[name].Extensions.Should().ContainKey("x-ms-visibility"); + acceptor.Schemas[name].Extensions["x-ms-visibility"].Should().BeOfType(); + (acceptor.Schemas[name].Extensions["x-ms-visibility"] as OpenApiString).Value.Should().Be(visibility.ToDisplayName(this._strategy)); + } + + [DataTestMethod] + [DataRow("string", "date-time")] + public void Given_Type_When_ParameterVisit_Invoked_Then_It_Should_Return_Result(string dataType, string dataFormat) + { + var result = this._visitor.ParameterVisit(typeof(DateTime), this._strategy); + + result.Type.Should().Be(dataType); + result.Format.Should().Be(dataFormat); + } + + [DataTestMethod] + [DataRow("string", "date-time")] + public void Given_Type_When_PayloadVisit_Invoked_Then_It_Should_Return_Null(string dataType, string dataFormat) + { + var result = this._visitor.PayloadVisit(typeof(DateTime), this._strategy); + + result.Type.Should().Be(dataType); + result.Format.Should().Be(dataFormat); + } + } +} diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/DecimalTypeVisitorTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/DecimalTypeVisitorTests.cs new file mode 100644 index 0000000..ef7ca50 --- /dev/null +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/DecimalTypeVisitorTests.cs @@ -0,0 +1,124 @@ +using System; +using System.Collections.Generic; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors; + +using FluentAssertions; + +using Microsoft.OpenApi.Any; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +using Newtonsoft.Json.Serialization; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Visitors +{ + [TestClass] + public class DecimalTypeVisitorTests + { + private IVisitor _visitor; + private NamingStrategy _strategy; + + [TestInitialize] + public void Init() + { + this._visitor = new DecimalTypeVisitor(); + this._strategy = new CamelCaseNamingStrategy(); + } + + [DataTestMethod] + [DataRow(typeof(decimal), false)] + public void Given_Type_When_IsNavigatable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsNavigatable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(decimal), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(decimal), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsParameterVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsParameterVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(decimal), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsPayloadVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsPayloadVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow("number", "double")] + public void Given_Type_When_Visit_Invoked_Then_It_Should_Return_Result(string dataType, string dataFormat) + { + var name = "hello"; + var acceptor = new OpenApiSchemaAcceptor(); + var type = new KeyValuePair(name, typeof(decimal)); + + this._visitor.Visit(acceptor, type, this._strategy); + + acceptor.Schemas.Should().ContainKey(name); + acceptor.Schemas[name].Type.Should().Be(dataType); + acceptor.Schemas[name].Format.Should().Be(dataFormat); + } + + [DataTestMethod] + [DataRow(OpenApiVisibilityType.Advanced)] + [DataRow(OpenApiVisibilityType.Important)] + [DataRow(OpenApiVisibilityType.Internal)] + public void Given_Attribute_When_Visit_Invoked_Then_It_Should_Return_Result(OpenApiVisibilityType visibility) + { + var name = "hello"; + var acceptor = new OpenApiSchemaAcceptor(); + var type = new KeyValuePair(name, typeof(decimal)); + var attribute = new OpenApiSchemaVisibilityAttribute(visibility); + + this._visitor.Visit(acceptor, type, this._strategy, attribute); + + acceptor.Schemas[name].Extensions.Should().ContainKey("x-ms-visibility"); + acceptor.Schemas[name].Extensions["x-ms-visibility"].Should().BeOfType(); + (acceptor.Schemas[name].Extensions["x-ms-visibility"] as OpenApiString).Value.Should().Be(visibility.ToDisplayName(this._strategy)); + } + + [DataTestMethod] + [DataRow("number", "double")] + public void Given_Type_When_ParameterVisit_Invoked_Then_It_Should_Return_Result(string dataType, string dataFormat) + { + var result = this._visitor.ParameterVisit(typeof(decimal), this._strategy); + + result.Type.Should().Be(dataType); + result.Format.Should().Be(dataFormat); + } + + [DataTestMethod] + [DataRow("number", "double")] + public void Given_Type_When_PayloadVisit_Invoked_Then_It_Should_Return_Result(string dataType, string dataFormat) + { + var result = this._visitor.PayloadVisit(typeof(decimal), this._strategy); + + result.Type.Should().Be(dataType); + result.Format.Should().Be(dataFormat); + } + } +} diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/DictionaryObjectTypeVisitorTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/DictionaryObjectTypeVisitorTests.cs new file mode 100644 index 0000000..0d6c6d2 --- /dev/null +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/DictionaryObjectTypeVisitorTests.cs @@ -0,0 +1,169 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors; + +using FluentAssertions; + +using Microsoft.OpenApi.Any; +using Microsoft.OpenApi.Models; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +using Newtonsoft.Json.Serialization; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Visitors +{ + [TestClass] + public class DictionaryObjectTypeVisitorTests + { + private IVisitor _visitor; + private NamingStrategy _strategy; + + [TestInitialize] + public void Init() + { + this._visitor = new DictionaryObjectTypeVisitor(); + this._strategy = new CamelCaseNamingStrategy(); + } + + [DataTestMethod] + [DataRow(typeof(Dictionary), false)] + public void Given_Type_When_IsNavigatable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsNavigatable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(Dictionary), true)] + [DataRow(typeof(IDictionary), true)] + [DataRow(typeof(IReadOnlyDictionary), true)] + [DataRow(typeof(KeyValuePair), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(Dictionary), false)] + [DataRow(typeof(IDictionary), false)] + [DataRow(typeof(IReadOnlyDictionary), false)] + [DataRow(typeof(KeyValuePair), false)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsParameterVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsParameterVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(Dictionary), true)] + [DataRow(typeof(IDictionary), true)] + [DataRow(typeof(IReadOnlyDictionary), true)] + [DataRow(typeof(KeyValuePair), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsPayloadVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsPayloadVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(Dictionary), "object", null, "string", false, "string", 0)] + [DataRow(typeof(IDictionary), "object", null, "string", false, "string", 0)] + [DataRow(typeof(IReadOnlyDictionary), "object", null, "string", false, "string", 0)] + [DataRow(typeof(KeyValuePair), "object", null, "string", false, "string", 0)] + [DataRow(typeof(Dictionary), "object", null, "object", true, "fakeModel", 1)] + [DataRow(typeof(IDictionary), "object", null, "object", true, "fakeModel", 1)] + [DataRow(typeof(IReadOnlyDictionary), "object", null, "object", true, "fakeModel", 1)] + [DataRow(typeof(KeyValuePair), "object", null, "object", true, "fakeModel", 1)] + public void Given_Type_When_Visit_Invoked_Then_It_Should_Return_Result(Type dictionaryType, string dataType, string dataFormat, string additionalPropertyType, bool isReferential, string referenceId, int expected) + { + var name = "hello"; + var acceptor = new OpenApiSchemaAcceptor(); + var type = new KeyValuePair(name, dictionaryType); + + this._visitor.Visit(acceptor, type, this._strategy); + + acceptor.Schemas.Should().ContainKey(name); + acceptor.Schemas[name].Type.Should().Be(dataType); + acceptor.Schemas[name].Format.Should().Be(dataFormat); + + acceptor.Schemas[name].AdditionalProperties.Should().NotBeNull(); + acceptor.Schemas[name].AdditionalProperties.Type.Should().Be(additionalPropertyType); + + if (isReferential) + { + acceptor.Schemas[name].AdditionalProperties.Reference.Type.Should().Be(ReferenceType.Schema); + acceptor.Schemas[name].AdditionalProperties.Reference.Id.Should().Be(referenceId); + } + + acceptor.RootSchemas.Count(p => p.Key == referenceId).Should().Be(expected); + } + + [DataTestMethod] + [DataRow(OpenApiVisibilityType.Advanced)] + [DataRow(OpenApiVisibilityType.Important)] + [DataRow(OpenApiVisibilityType.Internal)] + public void Given_Attribute_When_Visit_Invoked_Then_It_Should_Return_Result(OpenApiVisibilityType visibility) + { + var name = "hello"; + var acceptor = new OpenApiSchemaAcceptor(); + var type = new KeyValuePair(name, typeof(Dictionary)); + var attribute = new OpenApiSchemaVisibilityAttribute(visibility); + + this._visitor.Visit(acceptor, type, this._strategy, attribute); + + acceptor.Schemas[name].Extensions.Should().ContainKey("x-ms-visibility"); + acceptor.Schemas[name].Extensions["x-ms-visibility"].Should().BeOfType(); + (acceptor.Schemas[name].Extensions["x-ms-visibility"] as OpenApiString).Value.Should().Be(visibility.ToDisplayName(this._strategy)); + } + + [DataTestMethod] + [DataRow(typeof(Dictionary), "object", null, null)] + [DataRow(typeof(IDictionary), "object", null, null)] + [DataRow(typeof(IReadOnlyDictionary), "object", null, null)] + [DataRow(typeof(KeyValuePair), "object", null, null)] + public void Given_Type_When_ParameterVisit_Invoked_Then_It_Should_Return_Result(Type dictionaryType, string dataType, string dataFormat, OpenApiSchema expected) + { + var result = this._visitor.ParameterVisit(dictionaryType, this._strategy); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(Dictionary), "object", null, "string", "string")] + [DataRow(typeof(IDictionary), "object", null, "string", "string")] + [DataRow(typeof(IReadOnlyDictionary), "object", null, "string", "string")] + [DataRow(typeof(KeyValuePair), "object", null, "string", "string")] + [DataRow(typeof(Dictionary), "object", null, "object", "fakeModel")] + [DataRow(typeof(IDictionary), "object", null, "object", "fakeModel")] + [DataRow(typeof(IReadOnlyDictionary), "object", null, "object", "fakeModel")] + [DataRow(typeof(KeyValuePair), "object", null, "object", "fakeModel")] + public void Given_Type_When_PayloadVisit_Invoked_Then_It_Should_Return_Result(Type dictionaryType, string dataType, string dataFormat, string additionalPropertyType, string referenceId) + { + var result = this._visitor.PayloadVisit(dictionaryType, this._strategy); + + result.Type.Should().Be(dataType); + result.Format.Should().Be(dataFormat); + + result.AdditionalProperties.Should().NotBeNull(); + result.AdditionalProperties.Type.Should().Be(additionalPropertyType); + + result.AdditionalProperties.Reference.Type.Should().Be(ReferenceType.Schema); + result.AdditionalProperties.Reference.Id.Should().Be(referenceId); + } + } +} diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/DoubleTypeVisitorTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/DoubleTypeVisitorTests.cs new file mode 100644 index 0000000..9c1674f --- /dev/null +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/DoubleTypeVisitorTests.cs @@ -0,0 +1,124 @@ +using System; +using System.Collections.Generic; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors; + +using FluentAssertions; + +using Microsoft.OpenApi.Any; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +using Newtonsoft.Json.Serialization; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Visitors +{ + [TestClass] + public class DoubleTypeVisitorTests + { + private IVisitor _visitor; + private NamingStrategy _strategy; + + [TestInitialize] + public void Init() + { + this._visitor = new DoubleTypeVisitor(); + this._strategy = new CamelCaseNamingStrategy(); + } + + [DataTestMethod] + [DataRow(typeof(double), false)] + public void Given_Type_When_IsNavigatable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsNavigatable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(double), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(double), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsParameterVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsParameterVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(double), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsPayloadVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsPayloadVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow("number", "double")] + public void Given_Type_When_Visit_Invoked_Then_It_Should_Return_Result(string dataType, string dataFormat) + { + var name = "hello"; + var acceptor = new OpenApiSchemaAcceptor(); + var type = new KeyValuePair(name, typeof(double)); + + this._visitor.Visit(acceptor, type, this._strategy); + + acceptor.Schemas.Should().ContainKey(name); + acceptor.Schemas[name].Type.Should().Be(dataType); + acceptor.Schemas[name].Format.Should().Be(dataFormat); + } + + [DataTestMethod] + [DataRow(OpenApiVisibilityType.Advanced)] + [DataRow(OpenApiVisibilityType.Important)] + [DataRow(OpenApiVisibilityType.Internal)] + public void Given_Attribute_When_Visit_Invoked_Then_It_Should_Return_Result(OpenApiVisibilityType visibility) + { + var name = "hello"; + var acceptor = new OpenApiSchemaAcceptor(); + var type = new KeyValuePair(name, typeof(double)); + var attribute = new OpenApiSchemaVisibilityAttribute(visibility); + + this._visitor.Visit(acceptor, type, this._strategy, attribute); + + acceptor.Schemas[name].Extensions.Should().ContainKey("x-ms-visibility"); + acceptor.Schemas[name].Extensions["x-ms-visibility"].Should().BeOfType(); + (acceptor.Schemas[name].Extensions["x-ms-visibility"] as OpenApiString).Value.Should().Be(visibility.ToDisplayName(this._strategy)); + } + + [DataTestMethod] + [DataRow("number", "double")] + public void Given_Type_When_ParameterVisit_Invoked_Then_It_Should_Return_Result(string dataType, string dataFormat) + { + var result = this._visitor.ParameterVisit(typeof(double), this._strategy); + + result.Type.Should().Be(dataType); + result.Format.Should().Be(dataFormat); + } + + [DataTestMethod] + [DataRow("number", "double")] + public void Given_Type_When_PayloadVisit_Invoked_Then_It_Should_Return_Result(string dataType, string dataFormat) + { + var result = this._visitor.PayloadVisit(typeof(double), this._strategy); + + result.Type.Should().Be(dataType); + result.Format.Should().Be(dataFormat); + } + } +} diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/GuidObjectTypeVisitorTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/GuidObjectTypeVisitorTests.cs new file mode 100644 index 0000000..4203d15 --- /dev/null +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/GuidObjectTypeVisitorTests.cs @@ -0,0 +1,124 @@ +using System; +using System.Collections.Generic; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors; + +using FluentAssertions; + +using Microsoft.OpenApi.Any; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +using Newtonsoft.Json.Serialization; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Visitors +{ + [TestClass] + public class GuidObjectTypeVisitorTests + { + private IVisitor _visitor; + private NamingStrategy _strategy; + + [TestInitialize] + public void Init() + { + this._visitor = new GuidObjectTypeVisitor(); + this._strategy = new CamelCaseNamingStrategy(); + } + + [DataTestMethod] + [DataRow(typeof(Guid), false)] + public void Given_Type_When_IsNavigatable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsNavigatable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(Guid), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(Guid), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsParameterVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsParameterVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(Guid), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsPayloadVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsPayloadVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow("string", "uuid")] + public void Given_Type_When_Visit_Invoked_Then_It_Should_Return_Result(string dataType, string dataFormat) + { + var name = "hello"; + var acceptor = new OpenApiSchemaAcceptor(); + var type = new KeyValuePair(name, typeof(Guid)); + + this._visitor.Visit(acceptor, type, this._strategy); + + acceptor.Schemas.Should().ContainKey(name); + acceptor.Schemas[name].Type.Should().Be(dataType); + acceptor.Schemas[name].Format.Should().Be(dataFormat); + } + + [DataTestMethod] + [DataRow(OpenApiVisibilityType.Advanced)] + [DataRow(OpenApiVisibilityType.Important)] + [DataRow(OpenApiVisibilityType.Internal)] + public void Given_Attribute_When_Visit_Invoked_Then_It_Should_Return_Result(OpenApiVisibilityType visibility) + { + var name = "hello"; + var acceptor = new OpenApiSchemaAcceptor(); + var type = new KeyValuePair(name, typeof(Guid)); + var attribute = new OpenApiSchemaVisibilityAttribute(visibility); + + this._visitor.Visit(acceptor, type, this._strategy, attribute); + + acceptor.Schemas[name].Extensions.Should().ContainKey("x-ms-visibility"); + acceptor.Schemas[name].Extensions["x-ms-visibility"].Should().BeOfType(); + (acceptor.Schemas[name].Extensions["x-ms-visibility"] as OpenApiString).Value.Should().Be(visibility.ToDisplayName(this._strategy)); + } + + [DataTestMethod] + [DataRow("string", "uuid")] + public void Given_Type_When_ParameterVisit_Invoked_Then_It_Should_Return_Result(string dataType, string dataFormat) + { + var result = this._visitor.ParameterVisit(typeof(Guid), this._strategy); + + result.Type.Should().Be(dataType); + result.Format.Should().Be(dataFormat); + } + + [DataTestMethod] + [DataRow("string", "uuid")] + public void Given_Type_When_PayloadVisit_Invoked_Then_It_Should_Return_Result(string dataType, string dataFormat) + { + var result = this._visitor.PayloadVisit(typeof(Guid), this._strategy); + + result.Type.Should().Be(dataType); + result.Format.Should().Be(dataFormat); + } + } +} diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/Int16EnumTypeVisitorTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/Int16EnumTypeVisitorTests.cs new file mode 100644 index 0000000..6253a77 --- /dev/null +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/Int16EnumTypeVisitorTests.cs @@ -0,0 +1,158 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors; + +using FluentAssertions; + +using Microsoft.OpenApi.Any; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +using Newtonsoft.Json.Serialization; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Visitors +{ + [TestClass] + public class Int16EnumTypeVisitorTests + { + private IVisitor _visitor; + private NamingStrategy _strategy; + + [TestInitialize] + public void Init() + { + this._visitor = new Int16EnumTypeVisitor(); + this._strategy = new CamelCaseNamingStrategy(); + } + + [DataTestMethod] + [DataRow(typeof(FakeShortEnum), false)] + public void Given_Type_When_IsNavigatable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsNavigatable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(FakeShortEnum), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(FakeShortEnum), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsParameterVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsParameterVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(FakeShortEnum), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsPayloadVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsPayloadVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow("integer", "int32", typeof(FakeShortEnum))] + public void Given_Type_When_Visit_Invoked_Then_It_Should_Return_Result(string dataType, string dataFormat, Type enumType) + { + var name = "hello"; + var acceptor = new OpenApiSchemaAcceptor(); + var type = new KeyValuePair(name, typeof(FakeShortEnum)); + var enums = enumType.ToOpenApiInt16Collection(); + + this._visitor.Visit(acceptor, type, this._strategy); + + acceptor.Schemas.Should().ContainKey(name); + acceptor.Schemas[name].Type.Should().Be(dataType); + acceptor.Schemas[name].Format.Should().Be(dataFormat); + + for (var i = 0; i < acceptor.Schemas[name].Enum.Count; i++) + { + var @enum = acceptor.Schemas[name].Enum[i]; + @enum.Should().BeOfType(); + (@enum as OpenApiInteger).Value.Should().Be((enums[i] as OpenApiInteger).Value); + } + + (acceptor.Schemas[name].Default as OpenApiInteger).Value.Should().Be((enums.First() as OpenApiInteger).Value); + } + + [DataTestMethod] + [DataRow(OpenApiVisibilityType.Advanced)] + [DataRow(OpenApiVisibilityType.Important)] + [DataRow(OpenApiVisibilityType.Internal)] + public void Given_Attribute_When_Visit_Invoked_Then_It_Should_Return_Result(OpenApiVisibilityType visibility) + { + var name = "hello"; + var acceptor = new OpenApiSchemaAcceptor(); + var type = new KeyValuePair(name, typeof(FakeShortEnum)); + var attribute = new OpenApiSchemaVisibilityAttribute(visibility); + + this._visitor.Visit(acceptor, type, this._strategy, attribute); + + acceptor.Schemas[name].Extensions.Should().ContainKey("x-ms-visibility"); + acceptor.Schemas[name].Extensions["x-ms-visibility"].Should().BeOfType(); + (acceptor.Schemas[name].Extensions["x-ms-visibility"] as OpenApiString).Value.Should().Be(visibility.ToDisplayName(this._strategy)); + } + + [DataTestMethod] + [DataRow("integer", "int32", typeof(FakeShortEnum))] + public void Given_Type_When_ParameterVisit_Invoked_Then_It_Should_Return_Result(string dataType, string dataFormat, Type enumType) + { + var enums = enumType.ToOpenApiInt16Collection(); + + var result = this._visitor.ParameterVisit(typeof(FakeShortEnum), this._strategy); + + result.Type.Should().Be(dataType); + result.Format.Should().Be(dataFormat); + + for (var i = 0; i < result.Enum.Count; i++) + { + var @enum = result.Enum[i]; + @enum.Should().BeOfType(); + (@enum as OpenApiInteger).Value.Should().Be((enums[i] as OpenApiInteger).Value); + } + + (result.Default as OpenApiInteger).Value.Should().Be((enums.First() as OpenApiInteger).Value); + } + + [DataTestMethod] + [DataRow("integer", "int32", typeof(FakeShortEnum))] + public void Given_Type_When_PayloadVisit_Invoked_Then_It_Should_Return_Result(string dataType, string dataFormat, Type enumType) + { + var enums = enumType.ToOpenApiInt16Collection(); + + var result = this._visitor.PayloadVisit(typeof(FakeShortEnum), this._strategy); + + result.Type.Should().Be(dataType); + result.Format.Should().Be(dataFormat); + + for (var i = 0; i < result.Enum.Count; i++) + { + var @enum = result.Enum[i]; + @enum.Should().BeOfType(); + (@enum as OpenApiInteger).Value.Should().Be((enums[i] as OpenApiInteger).Value); + } + + (result.Default as OpenApiInteger).Value.Should().Be((enums.First() as OpenApiInteger).Value); + } + } +} diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/Int16TypeVisitorTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/Int16TypeVisitorTests.cs new file mode 100644 index 0000000..e1dea04 --- /dev/null +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/Int16TypeVisitorTests.cs @@ -0,0 +1,124 @@ +using System; +using System.Collections.Generic; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors; + +using FluentAssertions; + +using Microsoft.OpenApi.Any; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +using Newtonsoft.Json.Serialization; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Visitors +{ + [TestClass] + public class Int16TypeVisitorTests + { + private IVisitor _visitor; + private NamingStrategy _strategy; + + [TestInitialize] + public void Init() + { + this._visitor = new Int16TypeVisitor(); + this._strategy = new CamelCaseNamingStrategy(); + } + + [DataTestMethod] + [DataRow(typeof(short), false)] + public void Given_Type_When_IsNavigatable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsNavigatable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(short), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(short), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsParameterVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsParameterVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(short), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsPayloadVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsPayloadVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow("integer", "int32")] + public void Given_Type_When_Visit_Invoked_Then_It_Should_Return_Result(string dataType, string dataFormat) + { + var name = "hello"; + var acceptor = new OpenApiSchemaAcceptor(); + var type = new KeyValuePair(name, typeof(short)); + + this._visitor.Visit(acceptor, type, this._strategy); + + acceptor.Schemas.Should().ContainKey(name); + acceptor.Schemas[name].Type.Should().Be(dataType); + acceptor.Schemas[name].Format.Should().Be(dataFormat); + } + + [DataTestMethod] + [DataRow(OpenApiVisibilityType.Advanced)] + [DataRow(OpenApiVisibilityType.Important)] + [DataRow(OpenApiVisibilityType.Internal)] + public void Given_Attribute_When_Visit_Invoked_Then_It_Should_Return_Result(OpenApiVisibilityType visibility) + { + var name = "hello"; + var acceptor = new OpenApiSchemaAcceptor(); + var type = new KeyValuePair(name, typeof(short)); + var attribute = new OpenApiSchemaVisibilityAttribute(visibility); + + this._visitor.Visit(acceptor, type, this._strategy, attribute); + + acceptor.Schemas[name].Extensions.Should().ContainKey("x-ms-visibility"); + acceptor.Schemas[name].Extensions["x-ms-visibility"].Should().BeOfType(); + (acceptor.Schemas[name].Extensions["x-ms-visibility"] as OpenApiString).Value.Should().Be(visibility.ToDisplayName(this._strategy)); + } + + [DataTestMethod] + [DataRow("integer", "int32")] + public void Given_Type_When_ParameterVisit_Invoked_Then_It_Should_Return_Result(string dataType, string dataFormat) + { + var result = this._visitor.ParameterVisit(typeof(short), this._strategy); + + result.Type.Should().Be(dataType); + result.Format.Should().Be(dataFormat); + } + + [DataTestMethod] + [DataRow("integer", "int32")] + public void Given_Type_When_PayloadVisit_Invoked_Then_It_Should_Return_Result(string dataType, string dataFormat) + { + var result = this._visitor.PayloadVisit(typeof(short), this._strategy); + + result.Type.Should().Be(dataType); + result.Format.Should().Be(dataFormat); + } + } +} diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/Int32EnumTypeVisitorTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/Int32EnumTypeVisitorTests.cs new file mode 100644 index 0000000..5353a13 --- /dev/null +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/Int32EnumTypeVisitorTests.cs @@ -0,0 +1,158 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors; + +using FluentAssertions; + +using Microsoft.OpenApi.Any; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +using Newtonsoft.Json.Serialization; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Visitors +{ + [TestClass] + public class Int32EnumTypeVisitorTests + { + private IVisitor _visitor; + private NamingStrategy _strategy; + + [TestInitialize] + public void Init() + { + this._visitor = new Int32EnumTypeVisitor(); + this._strategy = new CamelCaseNamingStrategy(); + } + + [DataTestMethod] + [DataRow(typeof(FakeIntEnum), false)] + public void Given_Type_When_IsNavigatable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsNavigatable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(FakeIntEnum), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(FakeIntEnum), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsParameterVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsParameterVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(FakeIntEnum), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsPayloadVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsPayloadVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow("integer", "int32", typeof(FakeIntEnum))] + public void Given_Type_When_Visit_Invoked_Then_It_Should_Return_Result(string dataType, string dataFormat, Type enumType) + { + var name = "hello"; + var acceptor = new OpenApiSchemaAcceptor(); + var type = new KeyValuePair(name, typeof(FakeIntEnum)); + var enums = enumType.ToOpenApiInt32Collection(); + + this._visitor.Visit(acceptor, type, this._strategy); + + acceptor.Schemas.Should().ContainKey(name); + acceptor.Schemas[name].Type.Should().Be(dataType); + acceptor.Schemas[name].Format.Should().Be(dataFormat); + + for (var i = 0; i < acceptor.Schemas[name].Enum.Count; i++) + { + var @enum = acceptor.Schemas[name].Enum[i]; + @enum.Should().BeOfType(); + (@enum as OpenApiInteger).Value.Should().Be((enums[i] as OpenApiInteger).Value); + } + + (acceptor.Schemas[name].Default as OpenApiInteger).Value.Should().Be((enums.First() as OpenApiInteger).Value); + } + + [DataTestMethod] + [DataRow(OpenApiVisibilityType.Advanced)] + [DataRow(OpenApiVisibilityType.Important)] + [DataRow(OpenApiVisibilityType.Internal)] + public void Given_Attribute_When_Visit_Invoked_Then_It_Should_Return_Result(OpenApiVisibilityType visibility) + { + var name = "hello"; + var acceptor = new OpenApiSchemaAcceptor(); + var type = new KeyValuePair(name, typeof(FakeIntEnum)); + var attribute = new OpenApiSchemaVisibilityAttribute(visibility); + + this._visitor.Visit(acceptor, type, this._strategy, attribute); + + acceptor.Schemas[name].Extensions.Should().ContainKey("x-ms-visibility"); + acceptor.Schemas[name].Extensions["x-ms-visibility"].Should().BeOfType(); + (acceptor.Schemas[name].Extensions["x-ms-visibility"] as OpenApiString).Value.Should().Be(visibility.ToDisplayName(this._strategy)); + } + + [DataTestMethod] + [DataRow("integer", "int32", typeof(FakeIntEnum))] + public void Given_Type_When_ParameterVisit_Invoked_Then_It_Should_Return_Result(string dataType, string dataFormat, Type enumType) + { + var enums = enumType.ToOpenApiInt32Collection(); + + var result = this._visitor.ParameterVisit(typeof(FakeIntEnum), this._strategy); + + result.Type.Should().Be(dataType); + result.Format.Should().Be(dataFormat); + + for (var i = 0; i < result.Enum.Count; i++) + { + var @enum = result.Enum[i]; + @enum.Should().BeOfType(); + (@enum as OpenApiInteger).Value.Should().Be((enums[i] as OpenApiInteger).Value); + } + + (result.Default as OpenApiInteger).Value.Should().Be((enums.First() as OpenApiInteger).Value); + } + + [DataTestMethod] + [DataRow("integer", "int32", typeof(FakeIntEnum))] + public void Given_Type_When_PayloadVisit_Invoked_Then_It_Should_Return_Result(string dataType, string dataFormat, Type enumType) + { + var enums = enumType.ToOpenApiInt32Collection(); + + var result = this._visitor.PayloadVisit(typeof(FakeIntEnum), this._strategy); + + result.Type.Should().Be(dataType); + result.Format.Should().Be(dataFormat); + + for (var i = 0; i < result.Enum.Count; i++) + { + var @enum = result.Enum[i]; + @enum.Should().BeOfType(); + (@enum as OpenApiInteger).Value.Should().Be((enums[i] as OpenApiInteger).Value); + } + + (result.Default as OpenApiInteger).Value.Should().Be((enums.First() as OpenApiInteger).Value); + } + } +} diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/Int32TypeVisitorTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/Int32TypeVisitorTests.cs new file mode 100644 index 0000000..0e2d1ec --- /dev/null +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/Int32TypeVisitorTests.cs @@ -0,0 +1,124 @@ +using System; +using System.Collections.Generic; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors; + +using FluentAssertions; + +using Microsoft.OpenApi.Any; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +using Newtonsoft.Json.Serialization; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Visitors +{ + [TestClass] + public class Int32TypeVisitorTests + { + private IVisitor _visitor; + private NamingStrategy _strategy; + + [TestInitialize] + public void Init() + { + this._visitor = new Int32TypeVisitor(); + this._strategy = new CamelCaseNamingStrategy(); + } + + [DataTestMethod] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsNavigatable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsNavigatable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(int), true)] + [DataRow(typeof(string), false)] + public void Given_Type_When_IsVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(int), true)] + [DataRow(typeof(string), false)] + public void Given_Type_When_IsParameterVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsParameterVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(int), true)] + [DataRow(typeof(string), false)] + public void Given_Type_When_IsPayloadVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsPayloadVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow("integer", "int32")] + public void Given_Type_When_Visit_Invoked_Then_It_Should_Return_Result(string dataType, string dataFormat) + { + var name = "hello"; + var acceptor = new OpenApiSchemaAcceptor(); + var type = new KeyValuePair(name, typeof(int)); + + this._visitor.Visit(acceptor, type, this._strategy); + + acceptor.Schemas.Should().ContainKey(name); + acceptor.Schemas[name].Type.Should().Be(dataType); + acceptor.Schemas[name].Format.Should().Be(dataFormat); + } + + [DataTestMethod] + [DataRow(OpenApiVisibilityType.Advanced)] + [DataRow(OpenApiVisibilityType.Important)] + [DataRow(OpenApiVisibilityType.Internal)] + public void Given_Attribute_When_Visit_Invoked_Then_It_Should_Return_Result(OpenApiVisibilityType visibility) + { + var name = "hello"; + var acceptor = new OpenApiSchemaAcceptor(); + var type = new KeyValuePair(name, typeof(int)); + var attribute = new OpenApiSchemaVisibilityAttribute(visibility); + + this._visitor.Visit(acceptor, type, this._strategy, attribute); + + acceptor.Schemas[name].Extensions.Should().ContainKey("x-ms-visibility"); + acceptor.Schemas[name].Extensions["x-ms-visibility"].Should().BeOfType(); + (acceptor.Schemas[name].Extensions["x-ms-visibility"] as OpenApiString).Value.Should().Be(visibility.ToDisplayName(this._strategy)); + } + + [DataTestMethod] + [DataRow("integer", "int32")] + public void Given_Type_When_ParameterVisit_Invoked_Then_It_Should_Return_Result(string dataType, string dataFormat) + { + var result = this._visitor.ParameterVisit(typeof(int), this._strategy); + + result.Type.Should().Be(dataType); + result.Format.Should().Be(dataFormat); + } + + [DataTestMethod] + [DataRow("integer", "int32")] + public void Given_Type_When_PayloadVisit_Invoked_Then_It_Should_Return_Result(string dataType, string dataFormat) + { + var result = this._visitor.PayloadVisit(typeof(int), this._strategy); + + result.Type.Should().Be(dataType); + result.Format.Should().Be(dataFormat); + } + } +} diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/Int64EnumTypeVisitorTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/Int64EnumTypeVisitorTests.cs new file mode 100644 index 0000000..3329579 --- /dev/null +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/Int64EnumTypeVisitorTests.cs @@ -0,0 +1,158 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors; + +using FluentAssertions; + +using Microsoft.OpenApi.Any; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +using Newtonsoft.Json.Serialization; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Visitors +{ + [TestClass] + public class Int64EnumTypeVisitorTests + { + private IVisitor _visitor; + private NamingStrategy _strategy; + + [TestInitialize] + public void Init() + { + this._visitor = new Int64EnumTypeVisitor(); + this._strategy = new CamelCaseNamingStrategy(); + } + + [DataTestMethod] + [DataRow(typeof(FakeLongEnum), false)] + public void Given_Type_When_IsNavigatable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsNavigatable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(FakeLongEnum), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(FakeLongEnum), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsParameterVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsParameterVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(FakeLongEnum), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsPayloadVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsPayloadVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow("integer", "int64", typeof(FakeLongEnum))] + public void Given_Type_When_Visit_Invoked_Then_It_Should_Return_Result(string dataType, string dataFormat, Type enumType) + { + var name = "hello"; + var acceptor = new OpenApiSchemaAcceptor(); + var type = new KeyValuePair(name, typeof(FakeLongEnum)); + var enums = enumType.ToOpenApiInt64Collection(); + + this._visitor.Visit(acceptor, type, this._strategy); + + acceptor.Schemas.Should().ContainKey(name); + acceptor.Schemas[name].Type.Should().Be(dataType); + acceptor.Schemas[name].Format.Should().Be(dataFormat); + + for (var i = 0; i < acceptor.Schemas[name].Enum.Count; i++) + { + var @enum = acceptor.Schemas[name].Enum[i]; + @enum.Should().BeOfType(); + (@enum as OpenApiLong).Value.Should().Be((enums[i] as OpenApiLong).Value); + } + + (acceptor.Schemas[name].Default as OpenApiLong).Value.Should().Be((enums.First() as OpenApiLong).Value); + } + + [DataTestMethod] + [DataRow(OpenApiVisibilityType.Advanced)] + [DataRow(OpenApiVisibilityType.Important)] + [DataRow(OpenApiVisibilityType.Internal)] + public void Given_Attribute_When_Visit_Invoked_Then_It_Should_Return_Result(OpenApiVisibilityType visibility) + { + var name = "hello"; + var acceptor = new OpenApiSchemaAcceptor(); + var type = new KeyValuePair(name, typeof(FakeLongEnum)); + var attribute = new OpenApiSchemaVisibilityAttribute(visibility); + + this._visitor.Visit(acceptor, type, this._strategy, attribute); + + acceptor.Schemas[name].Extensions.Should().ContainKey("x-ms-visibility"); + acceptor.Schemas[name].Extensions["x-ms-visibility"].Should().BeOfType(); + (acceptor.Schemas[name].Extensions["x-ms-visibility"] as OpenApiString).Value.Should().Be(visibility.ToDisplayName(this._strategy)); + } + + [DataTestMethod] + [DataRow("integer", "int64", typeof(FakeLongEnum))] + public void Given_Type_When_ParameterVisit_Invoked_Then_It_Should_Return_Result(string dataType, string dataFormat, Type enumType) + { + var enums = enumType.ToOpenApiInt64Collection(); + + var result = this._visitor.ParameterVisit(typeof(FakeLongEnum), this._strategy); + + result.Type.Should().Be(dataType); + result.Format.Should().Be(dataFormat); + + for (var i = 0; i < result.Enum.Count; i++) + { + var @enum = result.Enum[i]; + @enum.Should().BeOfType(); + (@enum as OpenApiLong).Value.Should().Be((enums[i] as OpenApiLong).Value); + } + + (result.Default as OpenApiLong).Value.Should().Be((enums.First() as OpenApiLong).Value); + } + + [DataTestMethod] + [DataRow("integer", "int64", typeof(FakeLongEnum))] + public void Given_Type_When_PayloadVisit_Invoked_Then_It_Should_Return_Result(string dataType, string dataFormat, Type enumType) + { + var enums = enumType.ToOpenApiInt64Collection(); + + var result = this._visitor.PayloadVisit(typeof(FakeLongEnum), this._strategy); + + result.Type.Should().Be(dataType); + result.Format.Should().Be(dataFormat); + + for (var i = 0; i < result.Enum.Count; i++) + { + var @enum = result.Enum[i]; + @enum.Should().BeOfType(); + (@enum as OpenApiLong).Value.Should().Be((enums[i] as OpenApiLong).Value); + } + + (result.Default as OpenApiLong).Value.Should().Be((enums.First() as OpenApiLong).Value); + } + } +} diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/Int64TypeVisitorTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/Int64TypeVisitorTests.cs new file mode 100644 index 0000000..63b8513 --- /dev/null +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/Int64TypeVisitorTests.cs @@ -0,0 +1,124 @@ +using System; +using System.Collections.Generic; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors; + +using FluentAssertions; + +using Microsoft.OpenApi.Any; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +using Newtonsoft.Json.Serialization; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Visitors +{ + [TestClass] + public class Int64TypeVisitorTests + { + private IVisitor _visitor; + private NamingStrategy _strategy; + + [TestInitialize] + public void Init() + { + this._visitor = new Int64TypeVisitor(); + this._strategy = new CamelCaseNamingStrategy(); + } + + [DataTestMethod] + [DataRow(typeof(long), false)] + public void Given_Type_When_IsNavigatable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsNavigatable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(long), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(long), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsParameterVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsParameterVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(long), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsPayloadVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsPayloadVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow("integer", "int64")] + public void Given_Type_When_Visit_Invoked_Then_It_Should_Return_Result(string dataType, string dataFormat) + { + var name = "hello"; + var acceptor = new OpenApiSchemaAcceptor(); + var type = new KeyValuePair(name, typeof(long)); + + this._visitor.Visit(acceptor, type, this._strategy); + + acceptor.Schemas.Should().ContainKey(name); + acceptor.Schemas[name].Type.Should().Be(dataType); + acceptor.Schemas[name].Format.Should().Be(dataFormat); + } + + [DataTestMethod] + [DataRow(OpenApiVisibilityType.Advanced)] + [DataRow(OpenApiVisibilityType.Important)] + [DataRow(OpenApiVisibilityType.Internal)] + public void Given_Attribute_When_Visit_Invoked_Then_It_Should_Return_Result(OpenApiVisibilityType visibility) + { + var name = "hello"; + var acceptor = new OpenApiSchemaAcceptor(); + var type = new KeyValuePair(name, typeof(long)); + var attribute = new OpenApiSchemaVisibilityAttribute(visibility); + + this._visitor.Visit(acceptor, type, this._strategy, attribute); + + acceptor.Schemas[name].Extensions.Should().ContainKey("x-ms-visibility"); + acceptor.Schemas[name].Extensions["x-ms-visibility"].Should().BeOfType(); + (acceptor.Schemas[name].Extensions["x-ms-visibility"] as OpenApiString).Value.Should().Be(visibility.ToDisplayName(this._strategy)); + } + + [DataTestMethod] + [DataRow("integer", "int64")] + public void Given_Type_When_ParameterVisit_Invoked_Then_It_Should_Return_Result(string dataType, string dataFormat) + { + var result = this._visitor.ParameterVisit(typeof(long), this._strategy); + + result.Type.Should().Be(dataType); + result.Format.Should().Be(dataFormat); + } + + [DataTestMethod] + [DataRow("integer", "int64")] + public void Given_Type_When_PayloadVisit_Invoked_Then_It_Should_Return_Result(string dataType, string dataFormat) + { + var result = this._visitor.PayloadVisit(typeof(long), this._strategy); + + result.Type.Should().Be(dataType); + result.Format.Should().Be(dataFormat); + } + } +} diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/JObjectTypeVisitorTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/JObjectTypeVisitorTests.cs new file mode 100644 index 0000000..9195913 --- /dev/null +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/JObjectTypeVisitorTests.cs @@ -0,0 +1,132 @@ +using System; +using System.Collections.Generic; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors; + +using FluentAssertions; + +using Microsoft.OpenApi.Any; +using Microsoft.OpenApi.Models; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +using Newtonsoft.Json.Linq; +using Newtonsoft.Json.Serialization; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Visitors +{ + [TestClass] + public class JObjectTypeVisitorTests + { + private IVisitor _visitor; + private NamingStrategy _strategy; + + [TestInitialize] + public void Init() + { + this._visitor = new JObjectTypeVisitor(); + this._strategy = new CamelCaseNamingStrategy(); + } + + [DataTestMethod] + [DataRow(typeof(JObject), false)] + [DataRow(typeof(JToken), false)] + public void Given_Type_When_IsNavigatable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsNavigatable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(JObject), true)] + [DataRow(typeof(JToken), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(JObject), false)] + [DataRow(typeof(JToken), false)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsParameterVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsParameterVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(JObject), true)] + [DataRow(typeof(JToken), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsPayloadVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsPayloadVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(JObject), "object", null)] + [DataRow(typeof(JToken), "object", null)] + public void Given_Type_When_Visit_Invoked_Then_It_Should_Return_Result(Type objectType, string dataType, string dataFormat) + { + var name = "hello"; + var acceptor = new OpenApiSchemaAcceptor(); + var type = new KeyValuePair(name, objectType); + + this._visitor.Visit(acceptor, type, this._strategy); + + acceptor.Schemas.Should().ContainKey(name); + acceptor.Schemas[name].Type.Should().Be(dataType); + acceptor.Schemas[name].Format.Should().Be(dataFormat); + } + + [DataTestMethod] + [DataRow(OpenApiVisibilityType.Advanced)] + [DataRow(OpenApiVisibilityType.Important)] + [DataRow(OpenApiVisibilityType.Internal)] + public void Given_Attribute_When_Visit_Invoked_Then_It_Should_Return_Result(OpenApiVisibilityType visibility) + { + var name = "hello"; + var acceptor = new OpenApiSchemaAcceptor(); + var type = new KeyValuePair(name, typeof(JObject)); + var attribute = new OpenApiSchemaVisibilityAttribute(visibility); + + this._visitor.Visit(acceptor, type, this._strategy, attribute); + + acceptor.Schemas[name].Extensions.Should().ContainKey("x-ms-visibility"); + acceptor.Schemas[name].Extensions["x-ms-visibility"].Should().BeOfType(); + (acceptor.Schemas[name].Extensions["x-ms-visibility"] as OpenApiString).Value.Should().Be(visibility.ToDisplayName(this._strategy)); + } + + [DataTestMethod] + [DataRow(typeof(JObject), "object", null, null)] + [DataRow(typeof(JToken), "object", null, null)] + public void Given_Type_When_ParameterVisit_Invoked_Then_It_Should_Return_Result(Type objectType, string dataType, string dataFormat, OpenApiSchema expected) + { + var result = this._visitor.ParameterVisit(objectType, this._strategy); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(JObject), "object", null)] + [DataRow(typeof(JToken), "object", null)] + public void Given_Type_When_PayloadVisit_Invoked_Then_It_Should_Return_Result(Type objectType, string dataType, string dataFormat) + { + var result = this._visitor.PayloadVisit(objectType, this._strategy); + + result.Type.Should().Be(dataType); + result.Format.Should().Be(dataFormat); + } + } +} diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/ListObjectTypeVisitorTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/ListObjectTypeVisitorTests.cs new file mode 100644 index 0000000..3d16eb3 --- /dev/null +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/ListObjectTypeVisitorTests.cs @@ -0,0 +1,198 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors; + +using FluentAssertions; + +using Microsoft.OpenApi.Any; +using Microsoft.OpenApi.Models; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +using Newtonsoft.Json.Serialization; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Visitors +{ + [TestClass] + public class ListObjectTypeVisitorTests + { + private IVisitor _visitor; + private NamingStrategy _strategy; + + [TestInitialize] + public void Init() + { + this._visitor = new ListObjectTypeVisitor(); + this._strategy = new CamelCaseNamingStrategy(); + } + + [DataTestMethod] + [DataRow(typeof(List), false)] + public void Given_Type_When_IsNavigatable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsNavigatable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(List), true)] + [DataRow(typeof(IList), true)] + [DataRow(typeof(ICollection), true)] + [DataRow(typeof(IEnumerable), true)] + [DataRow(typeof(IReadOnlyList), true)] + [DataRow(typeof(IReadOnlyCollection), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(List), true)] + [DataRow(typeof(IList), true)] + [DataRow(typeof(ICollection), true)] + [DataRow(typeof(IEnumerable), true)] + [DataRow(typeof(IReadOnlyList), true)] + [DataRow(typeof(IReadOnlyCollection), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsParameterVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsParameterVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(List), true)] + [DataRow(typeof(IList), true)] + [DataRow(typeof(ICollection), true)] + [DataRow(typeof(IEnumerable), true)] + [DataRow(typeof(IReadOnlyList), true)] + [DataRow(typeof(IReadOnlyCollection), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsPayloadVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsPayloadVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(List), "array", null, "string", false, "string", 0)] + [DataRow(typeof(IList), "array", null, "string", false, "string", 0)] + [DataRow(typeof(ICollection), "array", null, "string", false, "string", 0)] + [DataRow(typeof(IEnumerable), "array", null, "string", false, "string", 0)] + [DataRow(typeof(IReadOnlyList), "array", null, "string", false, "string", 0)] + [DataRow(typeof(IReadOnlyCollection), "array", null, "string", false, "string", 0)] + [DataRow(typeof(List), "array", null, "object", true, "fakeModel", 1)] + [DataRow(typeof(IList), "array", null, "object", true, "fakeModel", 1)] + [DataRow(typeof(ICollection), "array", null, "object", true, "fakeModel", 1)] + [DataRow(typeof(IEnumerable), "array", null, "object", true, "fakeModel", 1)] + [DataRow(typeof(IReadOnlyList), "array", null, "object", true, "fakeModel", 1)] + [DataRow(typeof(IReadOnlyCollection), "array", null, "object", true, "fakeModel", 1)] + public void Given_Type_When_Visit_Invoked_Then_It_Should_Return_Result(Type listType, string dataType, string dataFormat, string itemType, bool isReferential, string referenceId, int expected) + { + var name = "hello"; + var acceptor = new OpenApiSchemaAcceptor(); + var type = new KeyValuePair(name, listType); + + this._visitor.Visit(acceptor, type, this._strategy); + + acceptor.Schemas.Should().ContainKey(name); + acceptor.Schemas[name].Type.Should().Be(dataType); + acceptor.Schemas[name].Format.Should().Be(dataFormat); + + acceptor.Schemas[name].Items.Should().NotBeNull(); + acceptor.Schemas[name].Items.Type.Should().Be(itemType); + + if (isReferential) + { + acceptor.Schemas[name].Items.Reference.Type.Should().Be(ReferenceType.Schema); + acceptor.Schemas[name].Items.Reference.Id.Should().Be(referenceId); + } + + acceptor.RootSchemas.Count(p => p.Key == referenceId).Should().Be(expected); + } + + [DataTestMethod] + [DataRow(OpenApiVisibilityType.Advanced)] + [DataRow(OpenApiVisibilityType.Important)] + [DataRow(OpenApiVisibilityType.Internal)] + public void Given_Attribute_When_Visit_Invoked_Then_It_Should_Return_Result(OpenApiVisibilityType visibility) + { + var name = "hello"; + var acceptor = new OpenApiSchemaAcceptor(); + var type = new KeyValuePair(name, typeof(List)); + var attribute = new OpenApiSchemaVisibilityAttribute(visibility); + + this._visitor.Visit(acceptor, type, this._strategy, attribute); + + acceptor.Schemas[name].Extensions.Should().ContainKey("x-ms-visibility"); + acceptor.Schemas[name].Extensions["x-ms-visibility"].Should().BeOfType(); + (acceptor.Schemas[name].Extensions["x-ms-visibility"] as OpenApiString).Value.Should().Be(visibility.ToDisplayName(this._strategy)); + } + + [DataTestMethod] + [DataRow(typeof(List), "array", null, "string", false)] + [DataRow(typeof(IList), "array", null, "string", false)] + [DataRow(typeof(ICollection), "array", null, "string", false)] + [DataRow(typeof(IEnumerable), "array", null, "string", false)] + [DataRow(typeof(IReadOnlyList), "array", null, "string", false)] + [DataRow(typeof(IReadOnlyCollection), "array", null, "string", false)] + [DataRow(typeof(List), "array", null, "object", true)] + [DataRow(typeof(IList), "array", null, "object", true)] + [DataRow(typeof(ICollection), "array", null, "object", true)] + [DataRow(typeof(IEnumerable), "array", null, "object", true)] + [DataRow(typeof(IReadOnlyList), "array", null, "object", true)] + [DataRow(typeof(IReadOnlyCollection), "array", null, "object", true)] + public void Given_Type_When_ParameterVisit_Invoked_Then_It_Should_Return_Result(Type listType, string dataType, string dataFormat, string itemType, bool isItemToBeNull) + { + var result = this._visitor.ParameterVisit(listType, this._strategy); + + result.Type.Should().Be(dataType); + result.Format.Should().Be(dataFormat); + + if (!isItemToBeNull) + { + result.Items.Should().NotBeNull(); + result.Items.Type.Should().Be(itemType); + } + } + + [DataTestMethod] + [DataRow(typeof(List), "array", null, "string", "string")] + [DataRow(typeof(IList), "array", null, "string", "string")] + [DataRow(typeof(ICollection), "array", null, "string", "string")] + [DataRow(typeof(IEnumerable), "array", null, "string", "string")] + [DataRow(typeof(IReadOnlyList), "array", null, "string", "string")] + [DataRow(typeof(IReadOnlyCollection), "array", null, "string", "string")] + [DataRow(typeof(List), "array", null, "object", "fakeModel")] + [DataRow(typeof(IList), "array", null, "object", "fakeModel")] + [DataRow(typeof(ICollection), "array", null, "object", "fakeModel")] + [DataRow(typeof(IEnumerable), "array", null, "object", "fakeModel")] + [DataRow(typeof(IReadOnlyList), "array", null, "object", "fakeModel")] + [DataRow(typeof(IReadOnlyCollection), "array", null, "object", "fakeModel")] + public void Given_Type_When_PayloadVisit_Invoked_Then_It_Should_Return_Result(Type listType, string dataType, string dataFormat, string itemType, string referenceId) + { + var result = this._visitor.PayloadVisit(listType, this._strategy); + + result.Type.Should().Be(dataType); + result.Format.Should().Be(dataFormat); + + result.Items.Should().NotBeNull(); + result.Items.Type.Should().Be(itemType); + + result.Items.Reference.Type.Should().Be(ReferenceType.Schema); + result.Items.Reference.Id.Should().Be(referenceId); + } + } +} diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/NullableObjectTypeVisitorTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/NullableObjectTypeVisitorTests.cs new file mode 100644 index 0000000..6a1e4c0 --- /dev/null +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/NullableObjectTypeVisitorTests.cs @@ -0,0 +1,130 @@ +using System; +using System.Collections.Generic; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors; + +using FluentAssertions; + +using Microsoft.OpenApi.Any; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +using Newtonsoft.Json.Serialization; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Visitors +{ + [TestClass] + public class NullableObjectTypeVisitorTests + { + private IVisitor _visitor; + private NamingStrategy _strategy; + + [TestInitialize] + public void Init() + { + this._visitor = new NullableObjectTypeVisitor(); + this._strategy = new CamelCaseNamingStrategy(); + } + + [DataTestMethod] + [DataRow(typeof(DateTime?), false)] + public void Given_Type_When_IsNavigatable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsNavigatable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(DateTime?), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(DateTime?), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsParameterVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsParameterVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(DateTime?), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsPayloadVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsPayloadVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(DateTime?), "string", "date-time", true)] + [DataRow(typeof(int?), "integer", "int32", true)] + public void Given_Type_When_Visit_Invoked_Then_It_Should_Return_Result(Type objectType, string dataType, string dataFormat, bool schemaNullable) + { + var name = "hello"; + var acceptor = new OpenApiSchemaAcceptor(); + var type = new KeyValuePair(name, objectType); + + this._visitor.Visit(acceptor, type, this._strategy); + + acceptor.Schemas.Should().ContainKey(name); + acceptor.Schemas[name].Type.Should().Be(dataType); + acceptor.Schemas[name].Format.Should().Be(dataFormat); + acceptor.Schemas[name].Nullable.Should().Be(schemaNullable); + } + + [DataTestMethod] + [DataRow(OpenApiVisibilityType.Advanced)] + [DataRow(OpenApiVisibilityType.Important)] + [DataRow(OpenApiVisibilityType.Internal)] + public void Given_Attribute_When_Visit_Invoked_Then_It_Should_Return_Result(OpenApiVisibilityType visibility) + { + var name = "hello"; + var acceptor = new OpenApiSchemaAcceptor(); + var type = new KeyValuePair(name, typeof(DateTime?)); + var attribute = new OpenApiSchemaVisibilityAttribute(visibility); + + this._visitor.Visit(acceptor, type, this._strategy, attribute); + + acceptor.Schemas[name].Extensions.Should().ContainKey("x-ms-visibility"); + acceptor.Schemas[name].Extensions["x-ms-visibility"].Should().BeOfType(); + (acceptor.Schemas[name].Extensions["x-ms-visibility"] as OpenApiString).Value.Should().Be(visibility.ToDisplayName(this._strategy)); + } + + [DataTestMethod] + [DataRow(typeof(DateTime?), "string", "date-time", true)] + [DataRow(typeof(int?), "integer", "int32", true)] + public void Given_Type_When_ParameterVisit_Invoked_Then_It_Should_Return_Result(Type objectType, string dataType, string dataFormat, bool schemaNullable) + { + var result = this._visitor.ParameterVisit(objectType, this._strategy); + + result.Type.Should().Be(dataType); + result.Format.Should().Be(dataFormat); + result.Nullable.Should().Be(schemaNullable); + } + + [DataTestMethod] + [DataRow(typeof(DateTime?), "string", "date-time", true)] + [DataRow(typeof(int?), "integer", "int32", true)] + public void Given_Type_When_PayloadVisit_Invoked_Then_It_Should_Return_Result(Type objectType, string dataType, string dataFormat, bool schemaNullable) + { + var result = this._visitor.PayloadVisit(objectType, this._strategy); + + result.Type.Should().Be(dataType); + result.Format.Should().Be(dataFormat); + result.Nullable.Should().Be(schemaNullable); + } + } +} diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/ObjectTypeVisitorTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/ObjectTypeVisitorTests.cs new file mode 100644 index 0000000..fb5c2e6 --- /dev/null +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/ObjectTypeVisitorTests.cs @@ -0,0 +1,132 @@ +using System; +using System.Collections.Generic; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors; + +using FluentAssertions; + +using Microsoft.OpenApi.Any; +using Microsoft.OpenApi.Models; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +using Newtonsoft.Json.Serialization; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Visitors +{ + [TestClass] + public class ObjectTypeVisitorTests + { + private IVisitor _visitor; + private NamingStrategy _strategy; + + [TestInitialize] + public void Init() + { + this._visitor = new ObjectTypeVisitor(); + this._strategy = new CamelCaseNamingStrategy(); + } + + [DataTestMethod] + [DataRow(typeof(FakeModel), true)] + public void Given_Type_When_IsNavigatable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsNavigatable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(FakeModel), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(FakeModel), false)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsParameterVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsParameterVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(FakeModel), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsPayloadVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsPayloadVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(FakeModel), "object", null, 2, 1, "fakeModel")] + public void Given_Type_When_Visit_Invoked_Then_It_Should_Return_Result(Type objectType, string dataType, string dataFormat, int requiredCount, int rootSchemaCount, string referenceId) + { + var name = "hello"; + var acceptor = new OpenApiSchemaAcceptor(); + var type = new KeyValuePair(name, objectType); + + this._visitor.Visit(acceptor, type, this._strategy); + + acceptor.Schemas.Should().ContainKey(name); + acceptor.Schemas[name].Type.Should().Be(dataType); + acceptor.Schemas[name].Format.Should().Be(dataFormat); + + acceptor.Schemas[name].Required.Count.Should().Be(requiredCount); + + acceptor.RootSchemas.Count.Should().Be(rootSchemaCount); + + acceptor.Schemas[name].Reference.Type.Should().Be(ReferenceType.Schema); + acceptor.Schemas[name].Reference.Id.Should().Be(referenceId); + } + + [DataTestMethod] + [DataRow(OpenApiVisibilityType.Advanced)] + [DataRow(OpenApiVisibilityType.Important)] + [DataRow(OpenApiVisibilityType.Internal)] + public void Given_Attribute_When_Visit_Invoked_Then_It_Should_Return_Result(OpenApiVisibilityType visibility) + { + var name = "hello"; + var acceptor = new OpenApiSchemaAcceptor(); + var type = new KeyValuePair(name, typeof(FakeModel)); + var attribute = new OpenApiSchemaVisibilityAttribute(visibility); + + this._visitor.Visit(acceptor, type, this._strategy, attribute); + + acceptor.Schemas[name].Extensions.Should().ContainKey("x-ms-visibility"); + acceptor.Schemas[name].Extensions["x-ms-visibility"].Should().BeOfType(); + (acceptor.Schemas[name].Extensions["x-ms-visibility"] as OpenApiString).Value.Should().Be(visibility.ToDisplayName(this._strategy)); + } + + [DataTestMethod] + [DataRow(typeof(FakeModel), "object", null, null)] + public void Given_Type_When_ParameterVisit_Invoked_Then_It_Should_Return_Result(Type objectType, string dataType, string dataFormat, OpenApiSchema expected) + { + var result = this._visitor.ParameterVisit(objectType, this._strategy); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(FakeModel), "object", null)] + public void Given_Type_When_PayloadVisit_Invoked_Then_It_Should_Return_Result(Type objectType, string dataType, string dataFormat) + { + var result = this._visitor.PayloadVisit(objectType, this._strategy); + + result.Type.Should().Be(dataType); + result.Format.Should().Be(dataFormat); + } + } +} diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/RecursiveObjectTypeVisitorTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/RecursiveObjectTypeVisitorTests.cs new file mode 100644 index 0000000..81c8985 --- /dev/null +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/RecursiveObjectTypeVisitorTests.cs @@ -0,0 +1,132 @@ +using System; +using System.Collections.Generic; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors; + +using FluentAssertions; + +using Microsoft.OpenApi.Any; +using Microsoft.OpenApi.Models; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +using Newtonsoft.Json.Serialization; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Visitors +{ + [TestClass] + public class RecursiveObjectTypeVisitorTests + { + private IVisitor _visitor; + private NamingStrategy _strategy; + + [TestInitialize] + public void Init() + { + this._visitor = new RecursiveObjectTypeVisitor(); + this._strategy = new CamelCaseNamingStrategy(); + } + + [DataTestMethod] + [DataRow(typeof(FakeRecursiveModel), true)] + public void Given_Type_When_IsNavigatable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsNavigatable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(FakeRecursiveModel), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(FakeRecursiveModel), false)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsParameterVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsParameterVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(FakeRecursiveModel), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsPayloadVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsPayloadVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(FakeRecursiveModel), "object", null, 1, 0, "fakeRecursiveModel")] + public void Given_Type_When_Visit_Invoked_Then_It_Should_Return_Result(Type objectType, string dataType, string dataFormat, int requiredCount, int rootSchemaCount, string referenceId) + { + var name = "hello"; + var acceptor = new OpenApiSchemaAcceptor(); + var type = new KeyValuePair(name, objectType); + + this._visitor.Visit(acceptor, type, this._strategy); + + acceptor.Schemas.Should().ContainKey(name); + acceptor.Schemas[name].Type.Should().Be(dataType); + acceptor.Schemas[name].Format.Should().Be(dataFormat); + + acceptor.Schemas[name].Required.Count.Should().Be(requiredCount); + + acceptor.RootSchemas.Count.Should().Be(rootSchemaCount); + + acceptor.Schemas[name].Reference.Type.Should().Be(ReferenceType.Schema); + acceptor.Schemas[name].Reference.Id.Should().Be(referenceId); + } + + [DataTestMethod] + [DataRow(OpenApiVisibilityType.Advanced)] + [DataRow(OpenApiVisibilityType.Important)] + [DataRow(OpenApiVisibilityType.Internal)] + public void Given_Attribute_When_Visit_Invoked_Then_It_Should_Return_Result(OpenApiVisibilityType visibility) + { + var name = "hello"; + var acceptor = new OpenApiSchemaAcceptor(); + var type = new KeyValuePair(name, typeof(FakeRecursiveModel)); + var attribute = new OpenApiSchemaVisibilityAttribute(visibility); + + this._visitor.Visit(acceptor, type, this._strategy, attribute); + + acceptor.Schemas[name].Extensions.Should().ContainKey("x-ms-visibility"); + acceptor.Schemas[name].Extensions["x-ms-visibility"].Should().BeOfType(); + (acceptor.Schemas[name].Extensions["x-ms-visibility"] as OpenApiString).Value.Should().Be(visibility.ToDisplayName(this._strategy)); + } + + [DataTestMethod] + [DataRow(typeof(FakeRecursiveModel), "object", null, null)] + public void Given_Type_When_ParameterVisit_Invoked_Then_It_Should_Return_Result(Type objectType, string dataType, string dataFormat, OpenApiSchema expected) + { + var result = this._visitor.ParameterVisit(objectType, this._strategy); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(FakeRecursiveModel), "object", null)] + public void Given_Type_When_PayloadVisit_Invoked_Then_It_Should_Return_Result(Type objectType, string dataType, string dataFormat) + { + var result = this._visitor.PayloadVisit(objectType, this._strategy); + + result.Type.Should().Be(dataType); + result.Format.Should().Be(dataFormat); + } + } +} diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/SingleTypeVisitorTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/SingleTypeVisitorTests.cs new file mode 100644 index 0000000..def09ad --- /dev/null +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/SingleTypeVisitorTests.cs @@ -0,0 +1,124 @@ +using System; +using System.Collections.Generic; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors; + +using FluentAssertions; + +using Microsoft.OpenApi.Any; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +using Newtonsoft.Json.Serialization; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Visitors +{ + [TestClass] + public class SingleTypeVisitorTests + { + private IVisitor _visitor; + private NamingStrategy _strategy; + + [TestInitialize] + public void Init() + { + this._visitor = new SingleTypeVisitor(); + this._strategy = new CamelCaseNamingStrategy(); + } + + [DataTestMethod] + [DataRow(typeof(float), false)] + public void Given_Type_When_IsNavigatable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsNavigatable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(float), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(float), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsParameterVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsParameterVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(float), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsPayloadVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsPayloadVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow("number", "float")] + public void Given_Type_When_Visit_Invoked_Then_It_Should_Return_Result(string dataType, string dataFormat) + { + var name = "hello"; + var acceptor = new OpenApiSchemaAcceptor(); + var type = new KeyValuePair(name, typeof(float)); + + this._visitor.Visit(acceptor, type, this._strategy); + + acceptor.Schemas.Should().ContainKey(name); + acceptor.Schemas[name].Type.Should().Be(dataType); + acceptor.Schemas[name].Format.Should().Be(dataFormat); + } + + [DataTestMethod] + [DataRow(OpenApiVisibilityType.Advanced)] + [DataRow(OpenApiVisibilityType.Important)] + [DataRow(OpenApiVisibilityType.Internal)] + public void Given_Attribute_When_Visit_Invoked_Then_It_Should_Return_Result(OpenApiVisibilityType visibility) + { + var name = "hello"; + var acceptor = new OpenApiSchemaAcceptor(); + var type = new KeyValuePair(name, typeof(float)); + var attribute = new OpenApiSchemaVisibilityAttribute(visibility); + + this._visitor.Visit(acceptor, type, this._strategy, attribute); + + acceptor.Schemas[name].Extensions.Should().ContainKey("x-ms-visibility"); + acceptor.Schemas[name].Extensions["x-ms-visibility"].Should().BeOfType(); + (acceptor.Schemas[name].Extensions["x-ms-visibility"] as OpenApiString).Value.Should().Be(visibility.ToDisplayName(this._strategy)); + } + + [DataTestMethod] + [DataRow("number", "float")] + public void Given_Type_When_ParameterVisit_Invoked_Then_It_Should_Return_Result(string dataType, string dataFormat) + { + var result = this._visitor.ParameterVisit(typeof(float), this._strategy); + + result.Type.Should().Be(dataType); + result.Format.Should().Be(dataFormat); + } + + [DataTestMethod] + [DataRow("number", "float")] + public void Given_Type_When_PayloadVisit_Invoked_Then_It_Should_Return_Result(string dataType, string dataFormat) + { + var result = this._visitor.PayloadVisit(typeof(float), this._strategy); + + result.Type.Should().Be(dataType); + result.Format.Should().Be(dataFormat); + } + } +} diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/StringEnumTypeVisitorTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/StringEnumTypeVisitorTests.cs new file mode 100644 index 0000000..e84aa6c --- /dev/null +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/StringEnumTypeVisitorTests.cs @@ -0,0 +1,158 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors; + +using FluentAssertions; + +using Microsoft.OpenApi.Any; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +using Newtonsoft.Json.Serialization; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Visitors +{ + [TestClass] + public class StringEnumTypeVisitorTests + { + private IVisitor _visitor; + private NamingStrategy _strategy; + + [TestInitialize] + public void Init() + { + this._visitor = new StringEnumTypeVisitor(); + this._strategy = new CamelCaseNamingStrategy(); + } + + [DataTestMethod] + [DataRow(typeof(FakeStringEnum), false)] + public void Given_Type_When_IsNavigatable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsNavigatable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(FakeStringEnum), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(FakeStringEnum), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsParameterVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsParameterVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(FakeStringEnum), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsPayloadVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsPayloadVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow("string", null, typeof(FakeStringEnum))] + public void Given_Type_When_Visit_Invoked_Then_It_Should_Return_Result(string dataType, string dataFormat, Type enumType) + { + var name = "hello"; + var acceptor = new OpenApiSchemaAcceptor(); + var type = new KeyValuePair(name, typeof(FakeStringEnum)); + var enums = enumType.ToOpenApiStringCollection(this._strategy); + + this._visitor.Visit(acceptor, type, this._strategy); + + acceptor.Schemas.Should().ContainKey(name); + acceptor.Schemas[name].Type.Should().Be(dataType); + acceptor.Schemas[name].Format.Should().Be(dataFormat); + + for (var i = 0; i < acceptor.Schemas[name].Enum.Count; i++) + { + var @enum = acceptor.Schemas[name].Enum[i]; + @enum.Should().BeOfType(); + (@enum as OpenApiString).Value.Should().Be((enums[i] as OpenApiString).Value); + } + + (acceptor.Schemas[name].Default as OpenApiString).Value.Should().Be((enums.First() as OpenApiString).Value); + } + + [DataTestMethod] + [DataRow(OpenApiVisibilityType.Advanced)] + [DataRow(OpenApiVisibilityType.Important)] + [DataRow(OpenApiVisibilityType.Internal)] + public void Given_Attribute_When_Visit_Invoked_Then_It_Should_Return_Result(OpenApiVisibilityType visibility) + { + var name = "hello"; + var acceptor = new OpenApiSchemaAcceptor(); + var type = new KeyValuePair(name, typeof(FakeStringEnum)); + var attribute = new OpenApiSchemaVisibilityAttribute(visibility); + + this._visitor.Visit(acceptor, type, this._strategy, attribute); + + acceptor.Schemas[name].Extensions.Should().ContainKey("x-ms-visibility"); + acceptor.Schemas[name].Extensions["x-ms-visibility"].Should().BeOfType(); + (acceptor.Schemas[name].Extensions["x-ms-visibility"] as OpenApiString).Value.Should().Be(visibility.ToDisplayName(this._strategy)); + } + + [DataTestMethod] + [DataRow("string", null, typeof(FakeStringEnum))] + public void Given_Type_When_ParameterVisit_Invoked_Then_It_Should_Return_Result(string dataType, string dataFormat, Type enumType) + { + var enums = enumType.ToOpenApiStringCollection(this._strategy); + + var result = this._visitor.ParameterVisit(typeof(FakeStringEnum), this._strategy); + + result.Type.Should().Be(dataType); + result.Format.Should().Be(dataFormat); + + for (var i = 0; i < result.Enum.Count; i++) + { + var @enum = result.Enum[i]; + @enum.Should().BeOfType(); + (@enum as OpenApiString).Value.Should().Be((enums[i] as OpenApiString).Value); + } + + (result.Default as OpenApiString).Value.Should().Be((enums.First() as OpenApiString).Value); + } + + [DataTestMethod] + [DataRow("string", null, typeof(FakeStringEnum))] + public void Given_Type_When_PayloadVisit_Invoked_Then_It_Should_Return_Result(string dataType, string dataFormat, Type enumType) + { + var enums = enumType.ToOpenApiStringCollection(this._strategy); + + var result = this._visitor.PayloadVisit(typeof(FakeStringEnum), this._strategy); + + result.Type.Should().Be(dataType); + result.Format.Should().Be(dataFormat); + + for (var i = 0; i < result.Enum.Count; i++) + { + var @enum = result.Enum[i]; + @enum.Should().BeOfType(); + (@enum as OpenApiString).Value.Should().Be((enums[i] as OpenApiString).Value); + } + + (result.Default as OpenApiString).Value.Should().Be((enums.First() as OpenApiString).Value); + } + } +} diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/StringTypeVisitorTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/StringTypeVisitorTests.cs new file mode 100644 index 0000000..8e6b9f6 --- /dev/null +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/StringTypeVisitorTests.cs @@ -0,0 +1,124 @@ +using System; +using System.Collections.Generic; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Attributes; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Enums; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Visitors; + +using FluentAssertions; + +using Microsoft.OpenApi.Any; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +using Newtonsoft.Json.Serialization; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Visitors +{ + [TestClass] + public class StringTypeVisitorTests + { + private IVisitor _visitor; + private NamingStrategy _strategy; + + [TestInitialize] + public void Init() + { + this._visitor = new StringTypeVisitor(); + this._strategy = new CamelCaseNamingStrategy(); + } + + [DataTestMethod] + [DataRow(typeof(string), false)] + public void Given_Type_When_IsNavigatable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsNavigatable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(string), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(string), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsParameterVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsParameterVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(string), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsPayloadVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsPayloadVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow("string", null)] + public void Given_Type_When_Visit_Invoked_Then_It_Should_Return_Result(string dataType, string dataFormat) + { + var name = "hello"; + var acceptor = new OpenApiSchemaAcceptor(); + var type = new KeyValuePair(name, typeof(string)); + + this._visitor.Visit(acceptor, type, this._strategy); + + acceptor.Schemas.Should().ContainKey(name); + acceptor.Schemas[name].Type.Should().Be(dataType); + acceptor.Schemas[name].Format.Should().Be(dataFormat); + } + + [DataTestMethod] + [DataRow(OpenApiVisibilityType.Advanced)] + [DataRow(OpenApiVisibilityType.Important)] + [DataRow(OpenApiVisibilityType.Internal)] + public void Given_Attribute_When_Visit_Invoked_Then_It_Should_Return_Result(OpenApiVisibilityType visibility) + { + var name = "hello"; + var acceptor = new OpenApiSchemaAcceptor(); + var type = new KeyValuePair(name, typeof(string)); + var attribute = new OpenApiSchemaVisibilityAttribute(visibility); + + this._visitor.Visit(acceptor, type, this._strategy, attribute); + + acceptor.Schemas[name].Extensions.Should().ContainKey("x-ms-visibility"); + acceptor.Schemas[name].Extensions["x-ms-visibility"].Should().BeOfType(); + (acceptor.Schemas[name].Extensions["x-ms-visibility"] as OpenApiString).Value.Should().Be(visibility.ToDisplayName(this._strategy)); + } + + [DataTestMethod] + [DataRow("string", null)] + public void Given_Type_When_ParameterVisit_Invoked_Then_It_Should_Return_Result(string dataType, string dataFormat) + { + var result = this._visitor.ParameterVisit(typeof(string), this._strategy); + + result.Type.Should().Be(dataType); + result.Format.Should().Be(dataFormat); + } + + [DataTestMethod] + [DataRow("string", null)] + public void Given_Type_When_PayloadVisit_Invoked_Then_It_Should_Return_Result(string dataType, string dataFormat) + { + var result = this._visitor.PayloadVisit(typeof(string), this._strategy); + + result.Type.Should().Be(dataType); + result.Format.Should().Be(dataFormat); + } + } +} diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/TypeVisitorTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/TypeVisitorTests.cs new file mode 100644 index 0000000..ee4f3a4 --- /dev/null +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/Visitors/TypeVisitorTests.cs @@ -0,0 +1,96 @@ +using System; + +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Abstractions; +using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes; + +using FluentAssertions; + +using Microsoft.OpenApi.Models; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +using Newtonsoft.Json.Serialization; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Visitors +{ + [TestClass] + public class TypeVisitorTests + { + private IVisitor _visitor; + private NamingStrategy _strategy; + + [TestInitialize] + public void Init() + { + this._visitor = new FakeTypeVisitor(); + this._strategy = new CamelCaseNamingStrategy(); + } + + [DataTestMethod] + [DataRow(typeof(string), false)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsNavigatable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsNavigatable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(string), false)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(string), false)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsParameterVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsParameterVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(string), false)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsPayloadVisitable_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = this._visitor.IsPayloadVisitable(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(FakeModel), true)] + [DataRow(typeof(int), false)] + public void Given_Type_When_IsReferential_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = (this._visitor as FakeTypeVisitor).IsTypeReferential(type); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(string), default(OpenApiSchema))] + public void Given_Type_When_ParameterVisit_Invoked_Then_It_Should_Return_Result(Type type, OpenApiSchema expected) + { + var result = this._visitor.ParameterVisit(type, this._strategy); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow(typeof(string), default(OpenApiSchema))] + public void Given_Type_When_PayloadVisit_Invoked_Then_It_Should_Return_Null(Type type, OpenApiSchema expected) + { + var result = this._visitor.PayloadVisit(type, this._strategy); + + result.Should().Be(expected); + } + } +} diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/host.json b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/host.json new file mode 100644 index 0000000..61e8c0b --- /dev/null +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/host.json @@ -0,0 +1,19 @@ +{ + "openApi": { + "info": { + "version": "3.0.0", + "title": "Open API Sample on Azure Functions (STATIC)", + "description": "A sample API that runs on Azure Functions (STATIC) 3.x using Open API specification - from **host.json**.", + "termsOfService": "https://github.com/aliencube/AzureFunctions.Extensions", + "contact": { + "name": "Aliencube Community", + "email": "no-reply@aliencube.org", + "url": "https://github.com/aliencube/AzureFunctions.Extensions/issues" + }, + "license": { + "name": "MIT", + "url": "http://opensource.org/licenses/MIT" + } + } + } +} diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV1/host.json b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/local.settings.json similarity index 75% rename from samples/Aliencube.AzureFunctions.FunctionAppV1/host.json rename to test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/local.settings.json index 7a73a41..0e0dcd2 100644 --- a/samples/Aliencube.AzureFunctions.FunctionAppV1/host.json +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/local.settings.json @@ -1,2 +1,3 @@ { + } \ No newline at end of file diff --git a/samples/Aliencube.AzureFunctions.FunctionAppV2/host.json b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/openapisettings.json similarity index 75% rename from samples/Aliencube.AzureFunctions.FunctionAppV2/host.json rename to test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/openapisettings.json index 7a73a41..0e0dcd2 100644 --- a/samples/Aliencube.AzureFunctions.FunctionAppV2/host.json +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests/openapisettings.json @@ -1,2 +1,3 @@ { + } \ No newline at end of file diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes/FakeEnum.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes/FakeEnum.cs deleted file mode 100644 index 441f1c5..0000000 --- a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes/FakeEnum.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Aliencube.AzureFunctions.Extensions.OpenApi.Attributes; - -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; - -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes -{ - /// - /// This specifies fake enum values. - /// - [JsonConverter(typeof(StringEnumConverter))] - public enum FakeEnum - { - Value1, - - [Display("lorem")] - Value2 - } -} diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes/FakeModelWithCircularRef.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes/FakeModelWithCircularRef.cs deleted file mode 100644 index e915649..0000000 --- a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes/FakeModelWithCircularRef.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes -{ - /// - /// This represents the fake model entity. - /// - public class FakeModelWithCircularRef - { - /// - /// Gets or sets the value. - /// - public string FakeProperty { get; set; } - public FakeModelWithCircularRefSub SubProperty { get; set; } - } -} diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes/FakeModelWithCircularRefSub.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes/FakeModelWithCircularRefSub.cs deleted file mode 100644 index 5421bf7..0000000 --- a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes/FakeModelWithCircularRefSub.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes -{ - /// - /// This represents the fake model entity. - /// - public class FakeModelWithCircularRefSub - { - /// - /// Gets or sets the value. - /// - public FakeModelWithCircularRef Circle { get; set; } - } -} diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes/FakeModelWithList.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes/FakeModelWithList.cs deleted file mode 100644 index 11ad1f3..0000000 --- a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes/FakeModelWithList.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.Collections.Generic; - -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes -{ - /// - /// This represents the fake model entity. - /// - public class FakeModelWithList - { - /// - /// Gets or sets the value. - /// - public FakeSubModel Parent { get; set; } - public List Items { get; set; } - } -} diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes/FakeQueryCollection.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes/FakeQueryCollection.cs deleted file mode 100644 index dce4fad..0000000 --- a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes/FakeQueryCollection.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System.Collections; -using System.Collections.Generic; - -using Microsoft.AspNetCore.Http; -using Microsoft.Extensions.Primitives; - -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes -{ - public class FakeQueryCollection : IQueryCollection - { - private readonly Dictionary _values; - - public FakeQueryCollection() - { - this._values = new Dictionary(); - } - - public StringValues this[string key] - { - get { return this._values[key]; } - set { this._values[key] = value; } - } - - public int Count => throw new System.NotImplementedException(); - - public ICollection Keys => throw new System.NotImplementedException(); - - public bool ContainsKey(string key) - { - throw new System.NotImplementedException(); - } - - public IEnumerator> GetEnumerator() - { - throw new System.NotImplementedException(); - } - - public bool TryGetValue(string key, out StringValues value) - { - throw new System.NotImplementedException(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - throw new System.NotImplementedException(); - } - } -} \ No newline at end of file diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes/IFakeBaseInterface.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes/IFakeBaseInterface.cs deleted file mode 100644 index 13a6bf1..0000000 --- a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes/IFakeBaseInterface.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes -{ - public interface IFakeBaseInterface - { - string Name { get; set; } - string City { get; set; } - - /// - /// Does something. - /// - /// Input value. - /// Output value. - bool DoSomething(bool input); - } -} \ No newline at end of file diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes/IFakeInheritedInterface.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes/IFakeInheritedInterface.cs deleted file mode 100644 index f21f7ca..0000000 --- a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes/IFakeInheritedInterface.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; - -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes -{ - public interface IFakeInheritedInterface : IFakeBaseInterface - { - DateTime Birthdate { get; set; } - double Age { get; set; } - } -} \ No newline at end of file diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Aliencube.AzureFunctions.Extensions.OpenApi.Tests.csproj b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Aliencube.AzureFunctions.Extensions.OpenApi.Tests.csproj index 320a46b..e0b7391 100644 --- a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Aliencube.AzureFunctions.Extensions.OpenApi.Tests.csproj +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Aliencube.AzureFunctions.Extensions.OpenApi.Tests.csproj @@ -15,11 +15,8 @@ - - - - - + + @@ -34,4 +31,11 @@ + + + + + + + diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Extensions/EnumExtensionsTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Extensions/EnumExtensionsTests.cs deleted file mode 100644 index 2d78a88..0000000 --- a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Extensions/EnumExtensionsTests.cs +++ /dev/null @@ -1,136 +0,0 @@ -using System; - -using Aliencube.AzureFunctions.Extensions.OpenApi.Enums; -using Aliencube.AzureFunctions.Extensions.OpenApi.Extensions; -using Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes; - -using FluentAssertions; - -using Microsoft.OpenApi; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Extensions -{ - [TestClass] - public class EnumExtensionsTests - { - [TestMethod] - public void Given_Enum_Method_Should_Return_Value() - { - var @enum = FakeEnum.Value1; - var name = EnumExtensions.ToDisplayName(@enum); - - name.Should().BeEquivalentTo(@enum.ToString()); - - @enum = FakeEnum.Value2; - name = EnumExtensions.ToDisplayName(@enum); - var expected = "lorem"; - - name.Should().BeEquivalentTo(expected); - } - - [TestMethod] - public void Given_TypeCode_ToDataType_Should_Throw_Exception() - { - Action action = () => EnumExtensions.ToDataType(null); - action.Should().Throw(); - } - - [TestMethod] - public void Given_TypeCode_ToDataType_Should_Return_Value() - { - var dataType = EnumExtensions.ToDataType(typeof(Int16)); - - dataType.Should().BeEquivalentTo("integer"); - - dataType = EnumExtensions.ToDataType(typeof(Single)); - - dataType.Should().BeEquivalentTo("number"); - - dataType = EnumExtensions.ToDataType(typeof(Boolean)); - - dataType.Should().BeEquivalentTo("boolean"); - - dataType = EnumExtensions.ToDataType(typeof(DateTime)); - - dataType.Should().BeEquivalentTo("string"); - - dataType = EnumExtensions.ToDataType(typeof(Guid)); - - dataType.Should().BeEquivalentTo("string"); - - dataType = EnumExtensions.ToDataType(typeof(object)); - - dataType.Should().BeEquivalentTo("object"); - } - - [TestMethod] - public void Given_TypeCode_ToDataFormat_Should_Throw_Exception() - { - Action action = () => EnumExtensions.ToDataFormat(null); - action.Should().Throw(); - } - - [TestMethod] - public void Given_TypeCode_ToDataFormat_Should_Return_Value() - { - var dataType = EnumExtensions.ToDataFormat(typeof(Int16)); - - dataType.Should().BeEquivalentTo("int32"); - - dataType = EnumExtensions.ToDataFormat(typeof(Int64)); - - dataType.Should().BeEquivalentTo("int64"); - - dataType = EnumExtensions.ToDataFormat(typeof(Single)); - - dataType.Should().BeEquivalentTo("float"); - - dataType = EnumExtensions.ToDataFormat(typeof(Double)); - - dataType.Should().BeEquivalentTo("double"); - - dataType = EnumExtensions.ToDataFormat(typeof(DateTime)); - - dataType.Should().BeEquivalentTo("date-time"); - - dataType = EnumExtensions.ToDataFormat(typeof(Guid)); - - dataType.Should().BeEquivalentTo("uuid"); - - dataType = EnumExtensions.ToDataFormat(typeof(object)); - - dataType.Should().BeNull(); - } - - [DataTestMethod] - [DataRow(OpenApiFormat.Json, "application/json")] - [DataRow(OpenApiFormat.Yaml, "application/yaml")] - public void Given_OpenApiFormat_When_GetContentType_Invoked_Then_It_Should_Return_Result(OpenApiFormat format, string expected) - { - var result = EnumExtensions.GetContentType(format); - - result.Should().Be(expected); - } - - [DataTestMethod] - [DataRow(OpenApiVersionType.V2, OpenApiSpecVersion.OpenApi2_0)] - [DataRow(OpenApiVersionType.V3, OpenApiSpecVersion.OpenApi3_0)] - public void Given_OpenApiVersionType_When_ToOpenApiSpecVersion_Invoked_Then_It_Should_Return_Result(OpenApiVersionType version, OpenApiSpecVersion expected) - { - var result = EnumExtensions.ToOpenApiSpecVersion(version); - - result.Should().Be(expected); - } - - [DataTestMethod] - [DataRow(OpenApiFormatType.Json, OpenApiFormat.Json)] - [DataRow(OpenApiFormatType.Yaml, OpenApiFormat.Yaml)] - public void Given_OpenApiFormatType_When_ToOpenApiFormat_Invoked_Then_It_Should_Return_Result(OpenApiFormatType format, OpenApiFormat expected) - { - var result = EnumExtensions.ToOpenApiFormat(format); - - result.Should().Be(expected); - } - } -} diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Extensions/OpenApiSchemaExtensionsTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Extensions/OpenApiSchemaExtensionsTests.cs deleted file mode 100644 index a1cd177..0000000 --- a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Extensions/OpenApiSchemaExtensionsTests.cs +++ /dev/null @@ -1,274 +0,0 @@ -using System; -using System.Collections.Generic; - -using Aliencube.AzureFunctions.Extensions.OpenApi.Attributes; -using Aliencube.AzureFunctions.Extensions.OpenApi.Enums; -using Aliencube.AzureFunctions.Extensions.OpenApi.Extensions; -using Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes; - -using FluentAssertions; - -using Microsoft.OpenApi.Any; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -using Newtonsoft.Json.Linq; -using Newtonsoft.Json.Serialization; - -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Extensions -{ - [TestClass] - public class OpenApiSchemaExtensionsTests - { - [TestMethod] - public void Given_Type_Null_It_Should_Throw_Exception() - { - Action action = () => OpenApiSchemaExtensions.ToOpenApiSchema(null, null, null); - - action.Should().Throw(); - } - - [TestMethod] - public void Given_Type_JObject_It_Should_Return_Result() - { - var type = typeof(JObject); - var strategy = new CamelCaseNamingStrategy(); - - var schema = OpenApiSchemaExtensions.ToOpenApiSchema(type, strategy); - - schema.Type.Should().BeEquivalentTo("object"); - } - - [TestMethod] - public void Given_Type_JToken_It_Should_Return_Result() - { - var type = typeof(JToken); - var strategy = new CamelCaseNamingStrategy(); - - var schema = OpenApiSchemaExtensions.ToOpenApiSchema(type, strategy); - - schema.Type.Should().BeEquivalentTo("object"); - } - - [TestMethod] - public void Given_Type_Nullable_It_Should_Return_Result() - { - var type = typeof(int?); - var strategy = new CamelCaseNamingStrategy(); - - var schema = OpenApiSchemaExtensions.ToOpenApiSchema(type, strategy); - - schema.Nullable.Should().BeTrue(); - schema.Type.Should().BeEquivalentTo("integer"); - schema.Format.Should().BeEquivalentTo("int32"); - } - - [TestMethod] - public void Given_Type_Simple_It_Should_Return_Result() - { - var type = typeof(int); - var strategy = new CamelCaseNamingStrategy(); - - var schema = OpenApiSchemaExtensions.ToOpenApiSchema(type, strategy); - - schema.Type.Should().BeEquivalentTo("integer"); - schema.Format.Should().BeEquivalentTo("int32"); - } - - [TestMethod] - public void Given_Visibility_It_Should_Return_Result() - { - var type = typeof(int); - var strategy = new CamelCaseNamingStrategy(); - var visibilityType = OpenApiVisibilityType.Important; - var visibility = new OpenApiSchemaVisibilityAttribute(visibilityType); - - var schema = OpenApiSchemaExtensions.ToOpenApiSchema(type, strategy, visibility); - - schema.Extensions.ContainsKey("x-ms-visibility").Should().BeTrue(); - schema.Extensions["x-ms-visibility"].Should().BeEquivalentTo(new OpenApiString(visibilityType.ToDisplayName())); - schema.Type.Should().BeEquivalentTo("integer"); - schema.Format.Should().BeEquivalentTo("int32"); - } - - [TestMethod] - public void Given_Dictionary_It_Should_Return_Result() - { - var type = typeof(Dictionary); - var strategy = new CamelCaseNamingStrategy(); - - var schema = OpenApiSchemaExtensions.ToOpenApiSchema(type, strategy); - - schema.Type.Should().BeEquivalentTo("object"); - schema.AdditionalProperties.Type.Should().BeEquivalentTo("integer"); - schema.AdditionalProperties.Format.Should().BeEquivalentTo("int32"); - } - - [TestMethod] - public void Given_IDictionary_It_Should_Return_Result() - { - var type = typeof(Dictionary); - var strategy = new CamelCaseNamingStrategy(); - - var schema = OpenApiSchemaExtensions.ToOpenApiSchema(type, strategy); - - schema.Type.Should().BeEquivalentTo("object"); - schema.AdditionalProperties.Type.Should().BeEquivalentTo("integer"); - schema.AdditionalProperties.Format.Should().BeEquivalentTo("int32"); - } - - [TestMethod] - public void Given_IDictionaryWithFakeModel_It_Should_Return_Result() - { - var type = typeof(Dictionary); - var strategy = new CamelCaseNamingStrategy(); - - var schema = OpenApiSchemaExtensions.ToOpenApiSchema(type, strategy); - - schema.Type.Should().BeEquivalentTo("object"); - schema.AdditionalProperties.Type.Should().BeEquivalentTo("object"); - } - - [TestMethod] - public void Given_GenericIList_Should_Be_Array_With_Matching_Type() - { - var list = typeof(IList); - var strategy = new CamelCaseNamingStrategy(); - - var result = list.ToOpenApiSchema(strategy); - - result.Type.Should().Be("array"); - result.Items.Type.Should().Be("string"); - } - - [TestMethod] - public void Given_GenericList_Should_Be_Array_With_Matching_Type() - { - var list = typeof(List); - var strategy = new CamelCaseNamingStrategy(); - - var result = list.ToOpenApiSchema(strategy); - - result.Type.Should().Be("array"); - result.Items.Type.Should().Be("string"); - } - - [TestMethod] - public void Given_UntypedList_Should_Be_Array_With_Object_Type() - { - var list = typeof(List<>); - var strategy = new CamelCaseNamingStrategy(); - - var result = list.ToOpenApiSchema(strategy); - - result.Type.Should().Be("array"); - result.Items.Type.Should().Be("object"); - } - - [TestMethod] - public void Given_Array_Should_Be_Array() - { - var list = typeof(string[]); - var strategy = new CamelCaseNamingStrategy(); - - var result = list.ToOpenApiSchema(strategy); - - result.Type.Should().Be("array"); - result.Items.Type.Should().Be("string"); - } - - [TestMethod] - public void Given_Object_Should_Not_Be_Array() - { - var list = typeof(string); - var strategy = new CamelCaseNamingStrategy(); - - var result = list.ToOpenApiSchema(strategy); - - result.Type.Should().NotBe("array"); - result.Items.Should().BeNull(); - } - - [TestMethod] - public void Given_Interface_With_Inheritance_Should_Contain_All_Properties() - { - var interfaceType = typeof(IFakeInheritedInterface); - var strategy = new CamelCaseNamingStrategy(); - - var result = interfaceType.ToOpenApiSchema(strategy); - - result.Properties.Count.Should().Be(4); - } - - [TestMethod] - public void Given_FakeModel_When_ToOpenApiSchemas_Invoked_Then_It_Should_Return_Result() - { - var type = typeof(FakeModel); - var subType = typeof(FakeSubModel); - var enumType = typeof(FakeEnum); - - var strategy = new CamelCaseNamingStrategy(); - - var schemas = OpenApiSchemaExtensions.ToOpenApiSchemas(type, strategy); - - schemas.Count.Should().Be(3); - - var schema = schemas[type.Name]; - var subSchema = schemas[subType.Name]; - var enumSchema = schemas[enumType.Name]; - - schema.Type.Should().Be("object"); - schema.Properties["fakeProperty"].Type.Should().BeEquivalentTo("string"); - schema.Properties["nullableInt"].Type.Should().BeEquivalentTo("integer"); - schema.Properties["nullableInt"].Nullable.Should().BeTrue(); - schema.Properties["subProperty"].Reference.Id.Should().BeEquivalentTo(subType.Name); - schema.Properties["enumProperty"].Reference.Id.Should().BeEquivalentTo(enumType.Name); - - subSchema.Type.Should().Be("object"); - subSchema.Properties["fakeSubModelProperty"].Type.Should().BeEquivalentTo("integer"); - - enumSchema.Type.Should().Be("string"); - enumSchema.Enum.Count.Should().Be(2); - } - - [TestMethod] - public void Given_FakeModelWithList_It_Should_Return_Result() - { - var type = typeof(FakeModelWithList); - var strategy = new CamelCaseNamingStrategy(); - - var schemas = OpenApiSchemaExtensions.ToOpenApiSchemas(type, strategy); - schemas.Count.Should().Be(2); - var fmSchema = schemas[type.Name]; - var fsmType = typeof(FakeSubModel); - var fsmSchema = schemas[fsmType.Name]; - fmSchema.Type.Should().Be("object"); - fmSchema.Properties["parent"].Reference.Id.Should().BeEquivalentTo(fsmType.Name); - fmSchema.Properties["items"].Type.Should().BeEquivalentTo("array"); - fmSchema.Properties["items"].Items.Reference.Id.Should().BeEquivalentTo(fsmType.Name); - - fsmSchema.Type.Should().Be("object"); - fsmSchema.Properties["fakeSubModelProperty"].Type.Should().BeEquivalentTo("integer"); - - - } - [TestMethod] - public void Given_FakeModelWithCircularRef_It_Should_Return_Result() - { - var type = typeof(FakeModelWithCircularRef); - var strategy = new CamelCaseNamingStrategy(); - - var schemas = OpenApiSchemaExtensions.ToOpenApiSchemas(type, strategy); - schemas.Count.Should().Be(2); - var fmSchema = schemas[type.Name]; - var fsmType = typeof(FakeModelWithCircularRefSub); - var fsmSchema = schemas[fsmType.Name]; - fmSchema.Type.Should().Be("object"); - fmSchema.Properties["subProperty"].Reference.Id.Should().BeEquivalentTo(fsmType.Name); - - fsmSchema.Type.Should().Be("object"); - fsmSchema.Properties["circle"].Reference.Id.Should().BeEquivalentTo(type.Name); - - - } - } -} diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Extensions/TypeExtensionsTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Extensions/TypeExtensionsTests.cs deleted file mode 100644 index b812340..0000000 --- a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/Extensions/TypeExtensionsTests.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Collections.Generic; - -using Aliencube.AzureFunctions.Extensions.OpenApi.Extensions; - -using FluentAssertions; - -using Microsoft.VisualStudio.TestTools.UnitTesting; - -using Newtonsoft.Json.Linq; - -namespace Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Extensions -{ - [TestClass] - public class TypeExtensionsTests - { - [TestMethod] - public void Given_IList_Should_Return_True() => - typeof(IList).IsOpenApiArray().Should().BeTrue(); - - [TestMethod] - public void Given_List_Should_Return_True() => - typeof(List).IsOpenApiArray().Should().BeTrue(); - - [TestMethod] - public void Given_Array_Method_Should_Return_True() => - typeof(string[]).IsOpenApiArray().Should().BeTrue(); - - [TestMethod] - public void Given_Object_That_Extends_List_Should_Return_False() => - typeof(JObject).IsOpenApiArray().Should().BeFalse(); - - [TestMethod] - public void Given_String_Method_Should_Return_False() => - typeof(string).IsOpenApiArray().Should().BeFalse(); - } -} \ No newline at end of file diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/OpenApiHttpTriggerContextTests.cs b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/OpenApiHttpTriggerContextTests.cs new file mode 100644 index 0000000..24ad6cb --- /dev/null +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/OpenApiHttpTriggerContextTests.cs @@ -0,0 +1,35 @@ +using FluentAssertions; + +using Microsoft.OpenApi; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace Aliencube.AzureFunctions.Extensions.OpenApi.Tests +{ + [TestClass] + public class OpenApiHttpTriggerContextTests + { + [DataTestMethod] + [DataRow("v2", OpenApiSpecVersion.OpenApi2_0)] + [DataRow("v3", OpenApiSpecVersion.OpenApi3_0)] + public void Given_Type_When_GetOpenApiSpecVersion_Invoked_Then_It_Should_Return_Result(string version, OpenApiSpecVersion expected) + { + var context = new OpenApiHttpTriggerContext(); + + var result = context.GetOpenApiSpecVersion(version); + + result.Should().Be(expected); + } + + [DataTestMethod] + [DataRow("yaml", OpenApiFormat.Yaml)] + [DataRow("json", OpenApiFormat.Json)] + public void Given_Type_When_GetOpenApiSpecVersion_Invoked_Then_It_Should_Return_Result(string format, OpenApiFormat expected) + { + var context = new OpenApiHttpTriggerContext(); + + var result = context.GetOpenApiFormat(format); + + result.Should().Be(expected); + } + } +} diff --git a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/host.json b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/host.json index 0e0dcd2..61e8c0b 100644 --- a/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/host.json +++ b/test/Aliencube.AzureFunctions.Extensions.OpenApi.Tests/host.json @@ -1,3 +1,19 @@ { - -} \ No newline at end of file + "openApi": { + "info": { + "version": "3.0.0", + "title": "Open API Sample on Azure Functions (STATIC)", + "description": "A sample API that runs on Azure Functions (STATIC) 3.x using Open API specification - from **host.json**.", + "termsOfService": "https://github.com/aliencube/AzureFunctions.Extensions", + "contact": { + "name": "Aliencube Community", + "email": "no-reply@aliencube.org", + "url": "https://github.com/aliencube/AzureFunctions.Extensions/issues" + }, + "license": { + "name": "MIT", + "url": "http://opensource.org/licenses/MIT" + } + } + } +} diff --git a/test/Aliencube.AzureFunctions.FunctionAppV2.Tests/Aliencube.AzureFunctions.FunctionAppV2.Tests.csproj b/test/Aliencube.AzureFunctions.FunctionAppV2.Tests/Aliencube.AzureFunctions.FunctionAppV2.Tests.csproj deleted file mode 100644 index d2f03b9..0000000 --- a/test/Aliencube.AzureFunctions.FunctionAppV2.Tests/Aliencube.AzureFunctions.FunctionAppV2.Tests.csproj +++ /dev/null @@ -1,23 +0,0 @@ - - - - - netcoreapp2.1 - - false - - - - - - - - - - - - - - - - diff --git a/test/Aliencube.AzureFunctions.FunctionAppV2.Tests/OpenApiHttpTriggerTests.cs b/test/Aliencube.AzureFunctions.FunctionAppV2.Tests/OpenApiHttpTriggerTests.cs deleted file mode 100644 index dfde87f..0000000 --- a/test/Aliencube.AzureFunctions.FunctionAppV2.Tests/OpenApiHttpTriggerTests.cs +++ /dev/null @@ -1,112 +0,0 @@ -using System; -using System.Linq; -using System.Threading.Tasks; - -using Aliencube.AzureFunctions.Extensions.OpenApi; -using Aliencube.AzureFunctions.Extensions.OpenApi.Configurations; -using Aliencube.AzureFunctions.FunctionAppCommon.Models; - -using FluentAssertions; - -using Microsoft.OpenApi; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -using Newtonsoft.Json.Linq; -using Newtonsoft.Json.Serialization; - -namespace Aliencube.AzureFunctions.FunctionAppV2.Tests -{ - [TestClass] - public class OpenApiHttpTriggerTests - { - [TestMethod] - public async Task Given_Naming_Strategy_Should_Vary_Case() - { - var document = new Document(new DocumentHelper(new RouteConstraintFilter())); - - var assembly = typeof(SampleHttpTrigger).Assembly; - var result = await document - .InitialiseDocument() - .Build(assembly, new DefaultNamingStrategy()) - .RenderAsync(OpenApiSpecVersion.OpenApi3_0, OpenApiFormat.Json) - .ConfigureAwait(false); - - var testPropName = nameof(SampleResponseModel.DateTimeOffsetValue); - - // Check that the property is defined as "DateTimeOffsetValue" in pascal case. - var pcResult = JObject.Parse(result); - var pcModel = pcResult.SelectToken("$.." + typeof(SampleResponseModel).Name); - var pcProperties = pcModel["properties"]; - pcProperties[testPropName].Should().NotBeNull(); - pcProperties[testPropName].HasValues.Should().BeTrue(); - - // Now run with camel casing - var ccResult = JObject.Parse(await document - .InitialiseDocument() - .Build(assembly, new CamelCaseNamingStrategy()) - .RenderAsync(OpenApiSpecVersion.OpenApi3_0, OpenApiFormat.Json) - .ConfigureAwait(false)); - - var ccModel = ccResult.SelectToken("$.." + typeof(SampleResponseModel).Name); - var ccProperties = ccModel["properties"]; - - var expectedName = char.ToLower(testPropName[0]) + testPropName.Substring(1); - - ccProperties[expectedName].Should().NotBeNull(); - ccProperties[expectedName].HasValues.Should().BeTrue(); - } - - [TestMethod] - public async Task Given_Enum_Type_With_StringConverter_Spec_Should_Contain_Enum_Names() - { - var document = new Document(new DocumentHelper(new RouteConstraintFilter())); - - var assembly = typeof(SampleHttpTrigger).Assembly; - var result = JObject.Parse(await document - .InitialiseDocument() - .Build(assembly, new DefaultNamingStrategy()) - .RenderAsync(OpenApiSpecVersion.OpenApi3_0, OpenApiFormat.Json) - .ConfigureAwait(false)); - - var enumPropToken = result.SelectToken( - $"$..{typeof(SampleResponseModel).Name}.properties.{nameof(SampleResponseModel.EnumValueAsString)}"); - - enumPropToken.Should().NotBeNull(); - - var enumRef = enumPropToken["$ref"]; - enumRef.Should().NotBeNull(); - var enumValues = result.SelectToken( - $"$..{typeof(StringEnum).Name}")["enum"]; - enumValues.Should().NotBeNull(); - - enumValues.Children().Select(t => t.Value()).Should() - .BeEquivalentTo(Enum.GetNames(typeof(StringEnum))); - } - - [TestMethod] - public async Task Given_Enum_Type_WithOut_StringConverter_Spec_Should_Contain_Enum_Numbers() - { - var document = new Document(new DocumentHelper(new RouteConstraintFilter())); - - var assembly = typeof(SampleHttpTrigger).Assembly; - var result = JObject.Parse(await document - .InitialiseDocument() - .Build(assembly, new DefaultNamingStrategy()) - .RenderAsync(OpenApiSpecVersion.OpenApi3_0, OpenApiFormat.Json) - .ConfigureAwait(false)); - - var enumPropToken = result.SelectToken( - $"$..{typeof(SampleResponseModel).Name}.properties.{nameof(SampleResponseModel.EnumValueAsNumber)}"); - - enumPropToken.Should().NotBeNull(); - - var enumRef = enumPropToken["$ref"]; - enumRef.Should().NotBeNull(); - var enumValues = result.SelectToken( - $"$..{typeof(NumericEnum).Name}")["enum"]; - enumValues.Should().NotBeNull(); - enumValues.Children().Select(t => t.Value()).Should() - .BeEquivalentTo(Enum.GetValues(typeof(NumericEnum))); - } - } -} \ No newline at end of file diff --git a/test/Aliencube.AzureFunctions.FunctionAppV2.Tests/SampleHttpTriggerTests.cs b/test/Aliencube.AzureFunctions.FunctionAppV2.Tests/SampleHttpTriggerTests.cs deleted file mode 100644 index 4e1669e..0000000 --- a/test/Aliencube.AzureFunctions.FunctionAppV2.Tests/SampleHttpTriggerTests.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System.Threading.Tasks; - -using Aliencube.AzureFunctions.Extensions.DependencyInjection.Abstractions; -using Aliencube.AzureFunctions.Extensions.OpenApi.Tests.Fakes; -using Aliencube.AzureFunctions.FunctionAppCommon.Functions; - -using FluentAssertions; - -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Microsoft.Extensions.Logging; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -using Moq; - -namespace Aliencube.AzureFunctions.FunctionAppV2.Tests -{ - /// - /// This represents the test entity for the class. - /// - [TestClass] - public class SampleHttpTriggerTests - { - [TestMethod] - public async Task Given_Request_Run_Should_Return_Result() - { - var message = "hello world"; - var result = new OkObjectResult(message); - - var function = new Mock(); - function.Setup(p => p.InvokeAsync(It.IsAny(), It.IsAny())).ReturnsAsync(result); - - var trigger = new SampleHttpTrigger(function.Object); - - var id = 1; - var category = "heros"; - - var query = new FakeQueryCollection(); - query["name"] = "ipsum"; - - var req = new Mock(); - req.SetupGet(p => p.Query).Returns(query); - - var log = new Mock(); - var response = await trigger.GetSample(req.Object, id, category, log.Object).ConfigureAwait(false); - - response.Should().BeOfType(); - (response as OkObjectResult).Value.Should().Be(message); - } - } -} \ No newline at end of file diff --git a/test/Aliencube.AzureFunctions.FunctionAppV2.Tests/SampleTimerTriggerTests.cs b/test/Aliencube.AzureFunctions.FunctionAppV2.Tests/SampleTimerTriggerTests.cs deleted file mode 100644 index 7a7735d..0000000 --- a/test/Aliencube.AzureFunctions.FunctionAppV2.Tests/SampleTimerTriggerTests.cs +++ /dev/null @@ -1,47 +0,0 @@ -//using System.Threading.Tasks; - -//using Aliencube.AzureFunctions.Extensions.DependencyInjection.Abstractions; -//using Aliencube.AzureFunctions.FunctionAppCommon.Functions; - -//using FluentAssertions; - -//using Microsoft.Azure.WebJobs; -//using Microsoft.Azure.WebJobs.Extensions.Timers; -//using Microsoft.Extensions.Logging; -//using Microsoft.VisualStudio.TestTools.UnitTesting; - -//using Moq; - -//namespace Aliencube.AzureFunctions.FunctionAppV2.Tests -//{ -// /// -// /// This represents the test entity for the class. -// /// -// [TestClass] -// public class SampleTimerTriggerTests -// { -// [TestMethod] -// public async Task Given_Timer_Run_Should_Return_Result() -// { -// var result = true; - -// var function = new Mock(); -// function.Setup(p => p.InvokeAsync(It.IsAny(), It.IsAny())).ReturnsAsync(result); - -// var factory = new Mock(); -// factory.Setup(p => p.Create(It.IsAny())).Returns(function.Object); -// factory.SetupProperty(p => p.ResultInvoked); - -// SampleTimerTrigger.Factory = factory.Object; - -// var schedule = new Mock(); -// var timer = new TimerInfo(schedule.Object, new ScheduleStatus()); -// var collector = new Mock>(); -// var log = new Mock(); - -// await SampleTimerTrigger.Run(timer, collector.Object, log.Object).ConfigureAwait(false); - -// factory.Object.ResultInvoked.Should().BeOfType().And.Be(true); -// } -// } -//} \ No newline at end of file