mirror of
https://github.com/ysoftdevs/wapifuzz.git
synced 2026-01-19 09:56:58 +01:00
Init WFuzz state
This commit is contained in:
63
parser/.gitattributes
vendored
Normal file
63
parser/.gitattributes
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
###############################################################################
|
||||
# Set default behavior to automatically normalize line endings.
|
||||
###############################################################################
|
||||
* text=auto
|
||||
|
||||
###############################################################################
|
||||
# Set default behavior for command prompt diff.
|
||||
#
|
||||
# This is need for earlier builds of msysgit that does not have it on by
|
||||
# default for csharp files.
|
||||
# Note: This is only used by command line
|
||||
###############################################################################
|
||||
#*.cs diff=csharp
|
||||
|
||||
###############################################################################
|
||||
# Set the merge driver for project and solution files
|
||||
#
|
||||
# Merging from the command prompt will add diff markers to the files if there
|
||||
# are conflicts (Merging from VS is not affected by the settings below, in VS
|
||||
# the diff markers are never inserted). Diff markers may cause the following
|
||||
# file extensions to fail to load in VS. An alternative would be to treat
|
||||
# these files as binary and thus will always conflict and require user
|
||||
# intervention with every merge. To do so, just uncomment the entries below
|
||||
###############################################################################
|
||||
#*.sln merge=binary
|
||||
#*.csproj merge=binary
|
||||
#*.vbproj merge=binary
|
||||
#*.vcxproj merge=binary
|
||||
#*.vcproj merge=binary
|
||||
#*.dbproj merge=binary
|
||||
#*.fsproj merge=binary
|
||||
#*.lsproj merge=binary
|
||||
#*.wixproj merge=binary
|
||||
#*.modelproj merge=binary
|
||||
#*.sqlproj merge=binary
|
||||
#*.wwaproj merge=binary
|
||||
|
||||
###############################################################################
|
||||
# behavior for image files
|
||||
#
|
||||
# image files are treated as binary by default.
|
||||
###############################################################################
|
||||
#*.jpg binary
|
||||
#*.png binary
|
||||
#*.gif binary
|
||||
|
||||
###############################################################################
|
||||
# diff behavior for common document formats
|
||||
#
|
||||
# Convert binary document formats to text before diffing them. This feature
|
||||
# is only available from the command line. Turn it on by uncommenting the
|
||||
# entries below.
|
||||
###############################################################################
|
||||
#*.doc diff=astextplain
|
||||
#*.DOC diff=astextplain
|
||||
#*.docx diff=astextplain
|
||||
#*.DOCX diff=astextplain
|
||||
#*.dot diff=astextplain
|
||||
#*.DOT diff=astextplain
|
||||
#*.pdf diff=astextplain
|
||||
#*.PDF diff=astextplain
|
||||
#*.rtf diff=astextplain
|
||||
#*.RTF diff=astextplain
|
||||
265
parser/.gitignore
vendored
Normal file
265
parser/.gitignore
vendored
Normal file
@@ -0,0 +1,265 @@
|
||||
## Custom ignores
|
||||
*.json
|
||||
|
||||
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
|
||||
# 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
|
||||
29
parser/Models/Endpoint.cs
Normal file
29
parser/Models/Endpoint.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Models
|
||||
{
|
||||
public class Endpoint
|
||||
{
|
||||
public string Uri { get; }
|
||||
public List<Request> Requests { get; } = new List<Request>();
|
||||
|
||||
public Endpoint(string uri)
|
||||
{
|
||||
Uri = uri;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.Append("Uri: ");
|
||||
builder.AppendLine(Uri);
|
||||
builder.AppendLine("Requests: ");
|
||||
foreach (var request in Requests)
|
||||
{
|
||||
builder.AppendLine(request.ToString());
|
||||
}
|
||||
return builder.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
7
parser/Models/Models.csproj
Normal file
7
parser/Models/Models.csproj
Normal file
@@ -0,0 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
43
parser/Models/Request.cs
Normal file
43
parser/Models/Request.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Models
|
||||
{
|
||||
public class Request
|
||||
{
|
||||
public string Method { get; }
|
||||
public string Summary { get; set; }
|
||||
public List<UriAttribute> UriAttributes { get; set; }
|
||||
public List<Response> Responses { get; set; }
|
||||
public string BodyExample { get; set; }
|
||||
|
||||
public Dictionary<string, object> BodySchema { get; set; }
|
||||
|
||||
public Request(string method)
|
||||
{
|
||||
Method = method;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.Append("Type: ");
|
||||
builder.AppendLine(Method);
|
||||
builder.Append("Summary: ");
|
||||
builder.AppendLine(Summary);
|
||||
builder.AppendLine("Uri Attributes: ");
|
||||
foreach (var attribute in UriAttributes)
|
||||
{
|
||||
builder.AppendLine(attribute.ToString());
|
||||
}
|
||||
builder.AppendLine("Responses: ");
|
||||
foreach (var response in Responses)
|
||||
{
|
||||
builder.AppendLine(response.ToString());
|
||||
}
|
||||
builder.Append("BodyExample: ");
|
||||
builder.AppendLine(BodyExample);
|
||||
return builder.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
15
parser/Models/Response.cs
Normal file
15
parser/Models/Response.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
|
||||
namespace Models
|
||||
{
|
||||
public class Response
|
||||
{
|
||||
public int StatusCode { get; set; }
|
||||
public string Example { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"Status code: {StatusCode}{Environment.NewLine}Example: {Example}";
|
||||
}
|
||||
}
|
||||
}
|
||||
25
parser/Models/UriAttribute.cs
Normal file
25
parser/Models/UriAttribute.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
|
||||
namespace Models
|
||||
{
|
||||
public class UriAttribute
|
||||
{
|
||||
public string Name { get; }
|
||||
public bool Required { get; }
|
||||
public string ExampleValue { get; set; }
|
||||
|
||||
public string Type { get; set; }
|
||||
public string Format { get; set; }
|
||||
|
||||
public UriAttribute(string name, bool required)
|
||||
{
|
||||
Name = name;
|
||||
Required = required;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"Name: {Name}{Environment.NewLine}Required: {Required}{Environment.NewLine}Example value: {ExampleValue}";
|
||||
}
|
||||
}
|
||||
}
|
||||
43
parser/OpenApiParser.sln
Normal file
43
parser/OpenApiParser.sln
Normal file
@@ -0,0 +1,43 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.29009.5
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Models", "Models\Models.csproj", "{168C8169-8DF0-45C2-97C0-A9D565F4A59A}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Parser", "Parser\Parser.csproj", "{5B556283-E412-482E-BFC3-BF2C99FB1D41}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenApiParserCLI", "OpenApiParserCLI\OpenApiParserCLI.csproj", "{476E98FC-1E96-4FD1-ACC5-996A30D58F09}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Parser.Tests", "Parser.Tests\Parser.Tests.csproj", "{7250D212-A4AC-405C-8ECE-86046CC3B3F4}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{168C8169-8DF0-45C2-97C0-A9D565F4A59A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{168C8169-8DF0-45C2-97C0-A9D565F4A59A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{168C8169-8DF0-45C2-97C0-A9D565F4A59A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{168C8169-8DF0-45C2-97C0-A9D565F4A59A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{5B556283-E412-482E-BFC3-BF2C99FB1D41}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{5B556283-E412-482E-BFC3-BF2C99FB1D41}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{5B556283-E412-482E-BFC3-BF2C99FB1D41}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{5B556283-E412-482E-BFC3-BF2C99FB1D41}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{476E98FC-1E96-4FD1-ACC5-996A30D58F09}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{476E98FC-1E96-4FD1-ACC5-996A30D58F09}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{476E98FC-1E96-4FD1-ACC5-996A30D58F09}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{476E98FC-1E96-4FD1-ACC5-996A30D58F09}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{7250D212-A4AC-405C-8ECE-86046CC3B3F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7250D212-A4AC-405C-8ECE-86046CC3B3F4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7250D212-A4AC-405C-8ECE-86046CC3B3F4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7250D212-A4AC-405C-8ECE-86046CC3B3F4}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {8701D52B-F8CB-4BB0-A09A-0E5BA566BA9D}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
16
parser/OpenApiParserCLI/OpenApiParserCLI.csproj
Normal file
16
parser/OpenApiParserCLI/OpenApiParserCLI.csproj
Normal file
@@ -0,0 +1,16 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Parser\Parser.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
67
parser/OpenApiParserCLI/Program.cs
Normal file
67
parser/OpenApiParserCLI/Program.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Models;
|
||||
using Newtonsoft.Json;
|
||||
using Parser;
|
||||
|
||||
namespace OpenApiParserCLI
|
||||
{
|
||||
static class Program
|
||||
{
|
||||
static int Main(string[] args)
|
||||
{
|
||||
if (args.Length != 2)
|
||||
{
|
||||
Console.WriteLine("Bad arguments provided.");
|
||||
PrintHelp();
|
||||
return 1;
|
||||
}
|
||||
|
||||
string openApiDocFilePath = args[0];
|
||||
string outputEndpointsFilePath = args[1];
|
||||
|
||||
if (!ValidateArguments(openApiDocFilePath, outputEndpointsFilePath))
|
||||
{
|
||||
PrintHelp();
|
||||
return 1;
|
||||
}
|
||||
|
||||
OpenApiDocument openApiDocument = OpenApiDocumentParser.ParseOpenApiDocument(openApiDocFilePath);
|
||||
List<Endpoint> endpoints = EndpointParser.ParseAllEndpoints(openApiDocument);
|
||||
string json = JsonConvert.SerializeObject(endpoints, Formatting.Indented);
|
||||
File.WriteAllText(outputEndpointsFilePath, json);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool ValidateArguments(string openApiDocFilePath, string outputEndpointsFilePath)
|
||||
{
|
||||
if (!File.Exists(openApiDocFilePath))
|
||||
{
|
||||
Console.WriteLine("Cannot find specified OpenApi file");
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
File.Create(outputEndpointsFilePath).Close();
|
||||
}
|
||||
catch
|
||||
{
|
||||
Console.WriteLine("Cannot create output file on defined path.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void PrintHelp()
|
||||
{
|
||||
Console.WriteLine("Arguments:");
|
||||
Console.WriteLine("1] OpenAPI doc. file");
|
||||
Console.WriteLine("2] Output file with JSON endpoints specification");
|
||||
Console.WriteLine("Example: parser.exe api.yaml output.json");
|
||||
}
|
||||
}
|
||||
}
|
||||
118
parser/Parser.Tests/AttributeParserTests.cs
Normal file
118
parser/Parser.Tests/AttributeParserTests.cs
Normal file
@@ -0,0 +1,118 @@
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.OpenApi.Any;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Parser.Tests
|
||||
{
|
||||
public class AttributeParserTests
|
||||
{
|
||||
|
||||
[TestCase(ParameterLocation.Cookie)]
|
||||
[TestCase(ParameterLocation.Header)]
|
||||
public void ParsingAttributeElsewhereThanInPathOrQueryShouldReturnNull(ParameterLocation parameterLocation)
|
||||
{
|
||||
OpenApiParameter parameter = new OpenApiParameter {In = parameterLocation};
|
||||
|
||||
var parsedAttribute = AttributeParser.ParseAttribute(parameter);
|
||||
|
||||
Assert.IsNull(parsedAttribute);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ParsingAttributeWithNoTypeOrFormatShouldReturnNull()
|
||||
{
|
||||
OpenApiParameter parameter = new OpenApiParameter {Schema = new OpenApiSchema {Type = null, Format = null}};
|
||||
|
||||
var parsedAttribute = AttributeParser.ParseAttribute(parameter);
|
||||
|
||||
Assert.IsNull(parsedAttribute);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ParsingPathAttributeWithValidContentExample()
|
||||
{
|
||||
string attributeContent = "test";
|
||||
OpenApiParameter parameter = new OpenApiParameter
|
||||
{
|
||||
In = ParameterLocation.Path, Schema = new OpenApiSchema {Type = "string", Format = null},
|
||||
Example = new OpenApiString(attributeContent)
|
||||
};
|
||||
|
||||
var parsedAttribute = AttributeParser.ParseAttribute(parameter);
|
||||
|
||||
Assert.AreEqual(attributeContent, parsedAttribute.ExampleValue);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ParsingQueryAttributeWithValidContentExample()
|
||||
{
|
||||
string attributeContent = "test";
|
||||
OpenApiParameter parameter = new OpenApiParameter
|
||||
{
|
||||
In = ParameterLocation.Query,
|
||||
Schema = new OpenApiSchema { Type = "string", Format = null },
|
||||
Example = new OpenApiString(attributeContent)
|
||||
};
|
||||
|
||||
var parsedAttribute = AttributeParser.ParseAttribute(parameter);
|
||||
|
||||
Assert.AreEqual(attributeContent, parsedAttribute.ExampleValue);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ParsingAttributeWithValidContentExamples()
|
||||
{
|
||||
string attributeContent = "test";
|
||||
OpenApiParameter parameter = new OpenApiParameter
|
||||
{
|
||||
In = ParameterLocation.Path, Schema = new OpenApiSchema {Type = "string", Format = null},
|
||||
Examples = new Dictionary<string, OpenApiExample>
|
||||
{
|
||||
{ "testKey 1", new OpenApiExample {Value = new OpenApiString(attributeContent)} },
|
||||
{ "testKey 2", new OpenApiExample {Value = new OpenApiString(attributeContent)} }
|
||||
}
|
||||
};
|
||||
|
||||
var parsedAttribute = AttributeParser.ParseAttribute(parameter);
|
||||
|
||||
Assert.AreEqual(attributeContent, parsedAttribute.ExampleValue);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ParsingAttributeWithInheritingExampleJustFromDataType()
|
||||
{
|
||||
OpenApiParameter parameter = new OpenApiParameter
|
||||
{
|
||||
In = ParameterLocation.Path,
|
||||
Schema = new OpenApiSchema { Type = "string", Format = null },
|
||||
Example = null,
|
||||
Examples = new Dictionary<string, OpenApiExample>()
|
||||
};
|
||||
|
||||
var parsedAttribute = AttributeParser.ParseAttribute(parameter);
|
||||
|
||||
Assert.IsNotNull(parsedAttribute);
|
||||
Assert.IsTrue(!string.IsNullOrEmpty(parsedAttribute.ExampleValue));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CheckThatParsedAttributeHasCorrectlySetDataTypeAndFormat()
|
||||
{
|
||||
OpenApiParameter parameter = new OpenApiParameter
|
||||
{
|
||||
In = ParameterLocation.Path,
|
||||
Schema = new OpenApiSchema { Type = "string", Format = null },
|
||||
Example = null,
|
||||
Examples = new Dictionary<string, OpenApiExample>()
|
||||
};
|
||||
|
||||
var parsedAttribute = AttributeParser.ParseAttribute(parameter);
|
||||
|
||||
Assert.IsNotNull(parsedAttribute);
|
||||
Assert.IsTrue(!string.IsNullOrEmpty(parsedAttribute.ExampleValue));
|
||||
Assert.AreEqual(parameter.Schema.Type, parsedAttribute.Type);
|
||||
Assert.AreEqual(parameter.Schema.Format, parsedAttribute.Format);
|
||||
}
|
||||
}
|
||||
}
|
||||
45
parser/Parser.Tests/ContentParserTests.cs
Normal file
45
parser/Parser.Tests/ContentParserTests.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.OpenApi.Any;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Parser.Tests
|
||||
{
|
||||
public class ContentParserTests
|
||||
{
|
||||
[Test]
|
||||
public void NoExampleFoundShouldReturnNull()
|
||||
{
|
||||
string parsedExample = ContentParser.GetStringExampleFromContent(null, new Dictionary<string, OpenApiExample>());
|
||||
|
||||
Assert.IsNull(parsedExample);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ParsingValidContentExample()
|
||||
{
|
||||
string attributeContent = "test";
|
||||
OpenApiString example = new OpenApiString(attributeContent);
|
||||
Dictionary<string, OpenApiExample> examples = new Dictionary<string, OpenApiExample>();
|
||||
|
||||
string parsedExample = ContentParser.GetStringExampleFromContent(example, examples);
|
||||
|
||||
Assert.AreEqual(attributeContent, parsedExample);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ParsingContentExamples()
|
||||
{
|
||||
string attributeContent = "test";
|
||||
Dictionary<string, OpenApiExample> examples = new Dictionary<string, OpenApiExample>
|
||||
{
|
||||
{"testKey 1", new OpenApiExample {Value = new OpenApiString(attributeContent)}},
|
||||
{"testKey 2", new OpenApiExample {Value = new OpenApiString(attributeContent)}}
|
||||
};
|
||||
|
||||
string parsedExample = ContentParser.GetStringExampleFromContent(null, examples);
|
||||
|
||||
Assert.AreEqual(attributeContent, parsedExample);
|
||||
}
|
||||
}
|
||||
}
|
||||
62
parser/Parser.Tests/EndpointParserTests.cs
Normal file
62
parser/Parser.Tests/EndpointParserTests.cs
Normal file
@@ -0,0 +1,62 @@
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using NUnit.Framework;
|
||||
using Models;
|
||||
|
||||
namespace Parser.Tests
|
||||
{
|
||||
public class EndpointParserTests
|
||||
{
|
||||
readonly OpenApiDocument _document = new OpenApiDocument {Paths = new OpenApiPaths()};
|
||||
private void AddTwoTestingPaths()
|
||||
{
|
||||
_document.Paths.Add("/path1", new OpenApiPathItem
|
||||
{
|
||||
Operations = new Dictionary<OperationType, OpenApiOperation>
|
||||
{
|
||||
{ OperationType.Get, new OpenApiOperation
|
||||
{
|
||||
Responses = new OpenApiResponses
|
||||
{
|
||||
{ "200", new OpenApiResponse()}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
_document.Paths.Add("/path2", new OpenApiPathItem
|
||||
{
|
||||
Operations = new Dictionary<OperationType, OpenApiOperation>
|
||||
{
|
||||
{ OperationType.Get, new OpenApiOperation
|
||||
{
|
||||
Responses = new OpenApiResponses
|
||||
{
|
||||
{ "201", new OpenApiResponse()}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DocumentWithoutAnyPathsShouldReturnEmptyList()
|
||||
{
|
||||
List<Endpoint> endpoints = EndpointParser.ParseAllEndpoints(_document);
|
||||
|
||||
Assert.IsEmpty(endpoints);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DocumentWithTwoPathsEachHavingSingleResponseShouldReturnTwoEndpoints()
|
||||
{
|
||||
AddTwoTestingPaths();
|
||||
|
||||
List<Endpoint> endpoints = EndpointParser.ParseAllEndpoints(_document);
|
||||
|
||||
Assert.AreEqual(2, endpoints.Count);
|
||||
}
|
||||
}
|
||||
}
|
||||
56
parser/Parser.Tests/ExamplesParserTests.cs
Normal file
56
parser/Parser.Tests/ExamplesParserTests.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.OpenApi.Any;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Parser.Tests
|
||||
{
|
||||
public class ExamplesParserTests
|
||||
{
|
||||
[TestCase("application/octet-stream")]
|
||||
[TestCase("application/pdf")]
|
||||
[TestCase("application/zip")]
|
||||
public void ParsingNotSupportedContentTypeShouldReturnNull(string contentType)
|
||||
{
|
||||
Assert.IsNull(ExamplesParser.ParseExample(new Dictionary<string, OpenApiMediaType> { { contentType, null } }));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ParsingPlainTextContent()
|
||||
{
|
||||
string plainText = "test";
|
||||
Dictionary<string, OpenApiMediaType> content = new Dictionary<string, OpenApiMediaType>
|
||||
{
|
||||
{"text/plain", new OpenApiMediaType {Example = new OpenApiString(plainText)}}
|
||||
};
|
||||
|
||||
string example = ExamplesParser.ParseExample(content);
|
||||
|
||||
Assert.AreEqual(plainText, example);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ParsingJsonContent()
|
||||
{
|
||||
string jsonTemplate = "{\n \"testKey1\": \"testValue\",\n \"testKey2\": \"testValue\"\n}";
|
||||
Dictionary<string, OpenApiMediaType> content = new Dictionary<string, OpenApiMediaType>
|
||||
{
|
||||
{
|
||||
"application/json", new OpenApiMediaType
|
||||
{
|
||||
Example = new OpenApiObject
|
||||
{
|
||||
{"testKey1", new OpenApiString("testValue") },
|
||||
{"testKey2", new OpenApiString("testValue") }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
string example = ExamplesParser.ParseExample(content);
|
||||
|
||||
Assert.AreEqual(jsonTemplate, example);
|
||||
}
|
||||
}
|
||||
}
|
||||
88
parser/Parser.Tests/OpenApiAnyConvertorTests.cs
Normal file
88
parser/Parser.Tests/OpenApiAnyConvertorTests.cs
Normal file
@@ -0,0 +1,88 @@
|
||||
using System;
|
||||
using Microsoft.OpenApi.Any;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Parser.Tests
|
||||
{
|
||||
public class OpenApiAnyConvertorTests
|
||||
{
|
||||
[Test]
|
||||
public void ConvertStringPrimitiveShouldReturnCorrectValue()
|
||||
{
|
||||
string value = "test";
|
||||
|
||||
Assert.AreEqual(value, OpenApiAnyConvertor.GetPrimitiveValue(new OpenApiString(value)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ConvertBooleanPrimitiveShouldReturnCorrectValue()
|
||||
{
|
||||
Assert.AreEqual("True", OpenApiAnyConvertor.GetPrimitiveValue(new OpenApiBoolean(true)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ConvertIntegerPrimitiveShouldReturnCorrectValue()
|
||||
{
|
||||
Assert.AreEqual("5", OpenApiAnyConvertor.GetPrimitiveValue(new OpenApiInteger(5)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ConvertBytePrimitiveShouldReturnCorrectValue()
|
||||
{
|
||||
var primitiveValue = OpenApiAnyConvertor.GetPrimitiveValue(new OpenApiByte(new byte[] { 7, 8 }));
|
||||
Assert.AreEqual("\a\b", primitiveValue);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ConvertBinaryPrimitiveShouldReturnCorrectValue()
|
||||
{
|
||||
var primitiveValue = OpenApiAnyConvertor.GetPrimitiveValue(new OpenApiBinary(new byte[] { 7, 8 }));
|
||||
Assert.AreEqual("0000011100001000", primitiveValue);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ConvertDatePrimitiveShouldReturnCorrectValue()
|
||||
{
|
||||
var primitiveValue = OpenApiAnyConvertor.GetPrimitiveValue(new OpenApiDate(DateTime.UnixEpoch));
|
||||
Assert.AreEqual("01/01/1970 00:00:00", primitiveValue);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ConvertDateTimePrimitiveShouldReturnCorrectValue()
|
||||
{
|
||||
var primitiveValue = OpenApiAnyConvertor.GetPrimitiveValue(new OpenApiDateTime(DateTime.UnixEpoch));
|
||||
Assert.AreEqual("1/1/1970 12:00:00 AM +00:00", primitiveValue);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ConvertObjectShouldReturnCorrectJson()
|
||||
{
|
||||
string expectedJson = "{\n \"testKey1\": \"testValue\",\n \"testKey2\": \"testValue\"\n}";
|
||||
var openApiObject = new OpenApiObject
|
||||
{
|
||||
{"testKey1", new OpenApiString("testValue")},
|
||||
{"testKey2", new OpenApiString("testValue")}
|
||||
};
|
||||
|
||||
var jsonValue = OpenApiAnyConvertor.GetJsonValue(openApiObject);
|
||||
|
||||
Assert.AreEqual(expectedJson, jsonValue);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ConvertArrayShouldReturnCorrectJson()
|
||||
{
|
||||
string expectedJson = "[\n {\n \"testKey1\": \"testValue\",\n \"testKey2\": \"testValue\"\n }\n]";
|
||||
var openApiObject = new OpenApiObject
|
||||
{
|
||||
{"testKey1", new OpenApiString("testValue")},
|
||||
{"testKey2", new OpenApiString("testValue")}
|
||||
};
|
||||
var openApiArray = new OpenApiArray {openApiObject};
|
||||
|
||||
var jsonValue = OpenApiAnyConvertor.GetJsonValue(openApiArray);
|
||||
|
||||
Assert.AreEqual(expectedJson, jsonValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
26
parser/Parser.Tests/Parser.Tests.csproj
Normal file
26
parser/Parser.Tests/Parser.Tests.csproj
Normal file
@@ -0,0 +1,26 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="nunit" Version="3.12.0" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.1.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Models\Models.csproj" />
|
||||
<ProjectReference Include="..\Parser\Parser.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.OpenApi">
|
||||
<HintPath>..\..\..\..\..\.nuget\packages\microsoft.openapi\1.1.3\lib\netstandard2.0\Microsoft.OpenApi.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Parser.Tests
|
||||
{
|
||||
public class PrimitiveDataTypeExampleGeneratorTests
|
||||
{
|
||||
[TestCase("integer", null, "42")]
|
||||
[TestCase("number", null, "42.0")]
|
||||
[TestCase("boolean", null, "True")]
|
||||
[TestCase("string", null, "example")]
|
||||
[TestCase("string", "byte", "example")]
|
||||
[TestCase("string", "binary", "01234567")]
|
||||
[TestCase("string", "date", "2002-10-02")]
|
||||
[TestCase("string", "date-time", "2002-10-02T10:00:00-05:00")]
|
||||
[TestCase("string", "password", "example")]
|
||||
public void ValidCombinationsShouldReturnValidValue(string type, string format, string expected)
|
||||
{
|
||||
string example = PrimitiveDataTypeExampleGenerator.GenerateExampleValueByType(type, format);
|
||||
Assert.AreEqual(expected, example);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void InvalidCombinationsShouldThrowAnException()
|
||||
{
|
||||
Assert.Throws<NotImplementedException>(() => PrimitiveDataTypeExampleGenerator.GenerateExampleValueByType("test", null));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
49
parser/Parser.Tests/RequestParserTests.cs
Normal file
49
parser/Parser.Tests/RequestParserTests.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.OpenApi.Any;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Models;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Parser.Tests
|
||||
{
|
||||
public class RequestParserTests
|
||||
{
|
||||
[Test]
|
||||
public void ValidRequestParsingShouldHaveCorrectValues()
|
||||
{
|
||||
string summary = "summary";
|
||||
string example = "test";
|
||||
|
||||
KeyValuePair<OperationType, OpenApiOperation> operation =
|
||||
new KeyValuePair<OperationType, OpenApiOperation>(OperationType.Get, new OpenApiOperation
|
||||
{
|
||||
Summary = summary,
|
||||
Parameters = new List<OpenApiParameter> { new OpenApiParameter
|
||||
{
|
||||
In = ParameterLocation.Path,
|
||||
Example = new OpenApiString(example),
|
||||
Schema = new OpenApiSchema {Type = "string", Format = null}
|
||||
} },
|
||||
RequestBody = new OpenApiRequestBody
|
||||
{
|
||||
Content = new Dictionary<string, OpenApiMediaType>
|
||||
{
|
||||
{ "text/plain", new OpenApiMediaType
|
||||
{
|
||||
Example = new OpenApiString(example)
|
||||
} }
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Request request = RequestParser.ParseRequest(operation);
|
||||
|
||||
Assert.AreEqual(summary, request.Summary);
|
||||
Assert.AreEqual(example, request.BodyExample);
|
||||
Assert.AreEqual(example, request.UriAttributes[0].ExampleValue);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
43
parser/Parser.Tests/ResponseParserTests.cs
Normal file
43
parser/Parser.Tests/ResponseParserTests.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.OpenApi.Any;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Models;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Parser.Tests
|
||||
{
|
||||
public class ResponseParserTests
|
||||
{
|
||||
[Test]
|
||||
public void ValidResponseParsingShouldHaveCorrectValues()
|
||||
{
|
||||
int statusCode = 200;
|
||||
string example = "example";
|
||||
|
||||
KeyValuePair<string, OpenApiResponse> openApiResponse = new KeyValuePair<string, OpenApiResponse>(statusCode.ToString(), new OpenApiResponse
|
||||
{
|
||||
Content = new Dictionary<string, OpenApiMediaType>
|
||||
{
|
||||
{ "text/plain", new OpenApiMediaType
|
||||
{
|
||||
Schema = new OpenApiSchema {Type = "string", Format = null},
|
||||
Example = new OpenApiString(example)
|
||||
} }
|
||||
}
|
||||
});
|
||||
|
||||
Response response = ResponseParser.ParseResponse(openApiResponse);
|
||||
|
||||
Assert.AreEqual(statusCode, response.StatusCode);
|
||||
Assert.AreEqual(example, response.Example);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void InvalidResponseStatusCodeShouldThrowException()
|
||||
{
|
||||
KeyValuePair<string, OpenApiResponse> openApiResponse = new KeyValuePair<string, OpenApiResponse>("invalid", new OpenApiResponse());
|
||||
Assert.Throws<NotImplementedException>(() => ResponseParser.ParseResponse(openApiResponse));
|
||||
}
|
||||
}
|
||||
}
|
||||
164
parser/Parser.Tests/SchemaParserTests.cs
Normal file
164
parser/Parser.Tests/SchemaParserTests.cs
Normal file
@@ -0,0 +1,164 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.OpenApi.Any;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Parser.Tests
|
||||
{
|
||||
public class SchemaParserTests
|
||||
{
|
||||
[TestCase("application/octet-stream")]
|
||||
[TestCase("application/pdf")]
|
||||
[TestCase("application/zip")]
|
||||
public void ParsingNotSupportedContentTypeShouldReturnNull(string contentType)
|
||||
{
|
||||
Assert.IsNull(SchemaParser.ParseSchema(new Dictionary<string, OpenApiMediaType> { { contentType, null } }));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SchemaWithRegularProperties()
|
||||
{
|
||||
string testingPropertyName = "testKey";
|
||||
string testingPropertyType = "string";
|
||||
string testingPropertyExample = "test";
|
||||
string testingPropertyFormat = null;
|
||||
|
||||
Dictionary<string, OpenApiMediaType> content = new Dictionary<string, OpenApiMediaType>
|
||||
{
|
||||
{
|
||||
"application/json", new OpenApiMediaType
|
||||
{
|
||||
Schema = new OpenApiSchema
|
||||
{
|
||||
Properties = new Dictionary<string, OpenApiSchema>
|
||||
{
|
||||
{
|
||||
testingPropertyName, new OpenApiSchema
|
||||
{
|
||||
Type = testingPropertyType,
|
||||
Example = new OpenApiString(testingPropertyExample),
|
||||
Title = testingPropertyName,
|
||||
Format = testingPropertyFormat
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Dictionary<string, object> parsedSchema = SchemaParser.ParseSchema(content);
|
||||
Dictionary<string, object> testingProperty = (Dictionary<string, object>) parsedSchema.First().Value;
|
||||
|
||||
Assert.AreEqual(testingPropertyName, parsedSchema.First().Key);
|
||||
|
||||
Assert.That(testingProperty.ContainsKey("Title"));
|
||||
Assert.That(testingProperty.ContainsKey("Type"));
|
||||
Assert.That(testingProperty.ContainsKey("Format"));
|
||||
Assert.That(testingProperty.ContainsKey("Example"));
|
||||
|
||||
Assert.AreEqual(testingPropertyName, testingProperty["Title"]);
|
||||
Assert.AreEqual(testingPropertyType, testingProperty["Type"]);
|
||||
Assert.AreEqual(testingPropertyFormat, testingProperty["Format"]);
|
||||
Assert.AreEqual(testingPropertyExample, testingProperty["Example"]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SchemaWithRegularArrayOfDoublesProperty()
|
||||
{
|
||||
string testingPropertyName = "testKey";
|
||||
string testingPropertyType = "array";
|
||||
string testingPropertyFormat = null;
|
||||
|
||||
string testingArrayItemType = "double";
|
||||
string testingArrayItemFormat = "number";
|
||||
|
||||
Dictionary<string, OpenApiMediaType> content = new Dictionary<string, OpenApiMediaType>
|
||||
{
|
||||
{
|
||||
"application/json", new OpenApiMediaType
|
||||
{
|
||||
Schema = new OpenApiSchema
|
||||
{
|
||||
Properties = new Dictionary<string, OpenApiSchema>
|
||||
{
|
||||
{
|
||||
testingPropertyName, new OpenApiSchema
|
||||
{
|
||||
Type = testingPropertyType,
|
||||
Title = testingPropertyName,
|
||||
Items = new OpenApiSchema { Type = testingArrayItemType, Format = testingArrayItemFormat },
|
||||
Format = testingPropertyFormat
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Dictionary<string, object> parsedSchema = SchemaParser.ParseSchema(content);
|
||||
Dictionary<string, object> testingProperty = (Dictionary<string, object>) parsedSchema.First().Value;
|
||||
Dictionary<string, object> arrayTypeDictionary = (Dictionary<string, object>) testingProperty["ArrayItemSchema"];
|
||||
|
||||
Assert.AreEqual(testingPropertyName, parsedSchema.First().Key);
|
||||
|
||||
Assert.That(arrayTypeDictionary.ContainsKey("Type"));
|
||||
Assert.That(arrayTypeDictionary.ContainsKey("Format"));
|
||||
|
||||
Assert.AreEqual(testingArrayItemType, arrayTypeDictionary["Type"]);
|
||||
Assert.AreEqual(testingArrayItemFormat, arrayTypeDictionary["Format"]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SchemaWithAdditionalProperties()
|
||||
{
|
||||
string testingPropertyName = "testKey";
|
||||
string testingPropertyType = "boolean";
|
||||
bool testingPropertyExample = true;
|
||||
string testingPropertyFormat = null;
|
||||
|
||||
Dictionary<string, OpenApiMediaType> content = new Dictionary<string, OpenApiMediaType>
|
||||
{
|
||||
{
|
||||
"application/json", new OpenApiMediaType
|
||||
{
|
||||
Schema = new OpenApiSchema
|
||||
{
|
||||
AdditionalPropertiesAllowed = true,
|
||||
AdditionalProperties = new OpenApiSchema {Properties = new Dictionary<string, OpenApiSchema>
|
||||
{
|
||||
{
|
||||
testingPropertyName, new OpenApiSchema
|
||||
{
|
||||
Type = testingPropertyType,
|
||||
Example = new OpenApiBoolean(testingPropertyExample),
|
||||
Title = testingPropertyName,
|
||||
Format = testingPropertyFormat
|
||||
}
|
||||
}
|
||||
}}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
Dictionary<string, object> firstAdditionalPropertyDictionary = (Dictionary<string, object>) SchemaParser.ParseSchema(content).First().Value;
|
||||
Dictionary<string, object> firstAdditionalPropertyItemDictionary = (Dictionary<string, object>)firstAdditionalPropertyDictionary.First().Value;
|
||||
|
||||
Assert.AreEqual(testingPropertyName, firstAdditionalPropertyDictionary.First().Key);
|
||||
|
||||
Assert.That(firstAdditionalPropertyItemDictionary.ContainsKey("Title"));
|
||||
Assert.That(firstAdditionalPropertyItemDictionary.ContainsKey("Type"));
|
||||
Assert.That(firstAdditionalPropertyItemDictionary.ContainsKey("Format"));
|
||||
Assert.That(firstAdditionalPropertyItemDictionary.ContainsKey("Example"));
|
||||
|
||||
Assert.AreEqual(testingPropertyName, firstAdditionalPropertyItemDictionary["Title"]);
|
||||
Assert.AreEqual(testingPropertyType, firstAdditionalPropertyItemDictionary["Type"]);
|
||||
Assert.AreEqual(testingPropertyFormat, firstAdditionalPropertyItemDictionary["Format"]);
|
||||
Assert.AreEqual(testingPropertyExample.ToString(), firstAdditionalPropertyItemDictionary["Example"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
31
parser/Parser/AttributeParser.cs
Normal file
31
parser/Parser/AttributeParser.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using System;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Models;
|
||||
|
||||
namespace Parser
|
||||
{
|
||||
public static class AttributeParser
|
||||
{
|
||||
public static UriAttribute ParseAttribute(OpenApiParameter parameter)
|
||||
{
|
||||
if (parameter.In == ParameterLocation.Path || parameter.In == ParameterLocation.Query)
|
||||
{
|
||||
if (parameter.Schema == null || parameter.Schema.Type == null && parameter.Schema.Format == null)
|
||||
{
|
||||
throw new ArgumentException("We do not know anything useful about passed URI parameter.");
|
||||
}
|
||||
|
||||
UriAttribute attribute = new UriAttribute(parameter.Name, parameter.Required)
|
||||
{
|
||||
ExampleValue = ContentParser.GetStringExampleFromContent(parameter.Example, parameter.Examples) ??
|
||||
ContentParser.GetSingleExample(parameter.Schema?.Example) ??
|
||||
PrimitiveDataTypeExampleGenerator.GenerateExampleValueByType(parameter.Schema.Type, parameter.Schema.Format),
|
||||
Type = parameter.Schema.Type,
|
||||
Format = parameter.Schema.Format
|
||||
};
|
||||
return attribute;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
42
parser/Parser/ContentParser.cs
Normal file
42
parser/Parser/ContentParser.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.OpenApi.Any;
|
||||
using Microsoft.OpenApi.Models;
|
||||
|
||||
namespace Parser
|
||||
{
|
||||
public static class ContentParser
|
||||
{
|
||||
public static string GetStringExampleFromContent(IOpenApiAny example, IDictionary<string, OpenApiExample> examples)
|
||||
{
|
||||
return GetSingleExample(example) ?? GetExampleFromExamplesDict(examples);
|
||||
}
|
||||
|
||||
public static string GetSingleExample(IOpenApiAny example)
|
||||
{
|
||||
return example != null ? GetStringFromAnyType(example) : null;
|
||||
}
|
||||
|
||||
// If there are more examples, take the first one
|
||||
// To the future consider creating request for each example
|
||||
static string GetExampleFromExamplesDict(IDictionary<string, OpenApiExample> examples)
|
||||
{
|
||||
return examples.Count > 0 ? GetSingleExample(examples.First().Value.Value) : null;
|
||||
}
|
||||
|
||||
static string GetStringFromAnyType(IOpenApiAny value)
|
||||
{
|
||||
switch (value.AnyType)
|
||||
{
|
||||
case AnyType.Primitive:
|
||||
return OpenApiAnyConvertor.GetPrimitiveValue(value);
|
||||
case AnyType.Object:
|
||||
case AnyType.Array:
|
||||
return OpenApiAnyConvertor.GetJsonValue(value);
|
||||
default:
|
||||
throw new NotImplementedException("This data example type is not supported yet!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
30
parser/Parser/EndpointParser.cs
Normal file
30
parser/Parser/EndpointParser.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Models;
|
||||
|
||||
namespace Parser
|
||||
{
|
||||
public static class EndpointParser
|
||||
{
|
||||
public static List<Endpoint> ParseAllEndpoints(OpenApiDocument openApiDocument)
|
||||
{
|
||||
List<Endpoint> endpoints = new List<Endpoint>();
|
||||
|
||||
foreach (var path in openApiDocument.Paths)
|
||||
{
|
||||
endpoints.Add(ParseEndpoint(path));
|
||||
}
|
||||
return endpoints;
|
||||
}
|
||||
|
||||
static Endpoint ParseEndpoint(KeyValuePair<string, OpenApiPathItem> path)
|
||||
{
|
||||
Endpoint endpoint = new Endpoint(path.Key);
|
||||
foreach (KeyValuePair<OperationType, OpenApiOperation> operation in path.Value.Operations)
|
||||
{
|
||||
endpoint.Requests.Add(RequestParser.ParseRequest(operation));
|
||||
}
|
||||
return endpoint;
|
||||
}
|
||||
}
|
||||
}
|
||||
37
parser/Parser/ExamplesParser.cs
Normal file
37
parser/Parser/ExamplesParser.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.OpenApi.Models;
|
||||
|
||||
namespace Parser
|
||||
{
|
||||
public static class ExamplesParser
|
||||
{
|
||||
static readonly List<string> SupportedContentTypes = new List<string> { "application/json", "text/plain" };
|
||||
|
||||
public static string ParseExample(IDictionary<string, OpenApiMediaType> contentDict)
|
||||
{
|
||||
foreach (var supportedContentType in SupportedContentTypes)
|
||||
{
|
||||
if (contentDict.ContainsKey(supportedContentType))
|
||||
return GetSpecificContentTypeExample(contentDict, supportedContentType);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
static string GetSpecificContentTypeExample(IDictionary<string, OpenApiMediaType> contentDict, string contentType)
|
||||
{
|
||||
var content = contentDict[contentType];
|
||||
return GetRealExample(content) ?? GetExampleFromSchema(content);
|
||||
}
|
||||
|
||||
static string GetRealExample(OpenApiMediaType content)
|
||||
{
|
||||
return ContentParser.GetStringExampleFromContent(content.Example, content.Examples);
|
||||
}
|
||||
|
||||
static string GetExampleFromSchema(OpenApiMediaType content)
|
||||
{
|
||||
return content.Schema != null ? ContentParser.GetStringExampleFromContent(content.Schema.Example, new Dictionary<string, OpenApiExample>()) : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
68
parser/Parser/OpenApiAnyConvertor.cs
Normal file
68
parser/Parser/OpenApiAnyConvertor.cs
Normal file
@@ -0,0 +1,68 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Microsoft.OpenApi.Any;
|
||||
using Microsoft.OpenApi.Writers;
|
||||
|
||||
namespace Parser
|
||||
{
|
||||
public static class OpenApiAnyConvertor
|
||||
{
|
||||
public static string GetPrimitiveValue(IOpenApiAny value)
|
||||
{
|
||||
IOpenApiPrimitive primitive = (IOpenApiPrimitive) value;
|
||||
|
||||
switch (primitive.PrimitiveType)
|
||||
{
|
||||
case PrimitiveType.String:
|
||||
OpenApiString stringValue = (OpenApiString) primitive;
|
||||
return stringValue.Value;
|
||||
case PrimitiveType.Boolean:
|
||||
OpenApiBoolean booleanValue = (OpenApiBoolean) primitive;
|
||||
return booleanValue.Value.ToString();
|
||||
case PrimitiveType.Integer:
|
||||
OpenApiInteger integerValue = (OpenApiInteger) primitive;
|
||||
return integerValue.Value.ToString();
|
||||
case PrimitiveType.Long:
|
||||
OpenApiLong longValue = (OpenApiLong) primitive;
|
||||
return longValue.Value.ToString();
|
||||
case PrimitiveType.Float:
|
||||
OpenApiFloat floatValue = (OpenApiFloat) primitive;
|
||||
return floatValue.Value.ToString(CultureInfo.InvariantCulture);
|
||||
case PrimitiveType.Double:
|
||||
OpenApiDouble doubleValue = (OpenApiDouble) primitive;
|
||||
return doubleValue.Value.ToString(CultureInfo.InvariantCulture);
|
||||
case PrimitiveType.Byte:
|
||||
OpenApiByte byteValue = (OpenApiByte) primitive;
|
||||
return Encoding.Default.GetString(byteValue.Value);
|
||||
case PrimitiveType.Binary:
|
||||
OpenApiBinary binaryValue = (OpenApiBinary) primitive;
|
||||
StringBuilder builder = new StringBuilder();
|
||||
foreach (byte byteVal in binaryValue.Value)
|
||||
{
|
||||
builder.Append(Convert.ToString(byteVal, 2).PadLeft(8, '0'));
|
||||
}
|
||||
return builder.ToString();
|
||||
case PrimitiveType.Date:
|
||||
OpenApiDate dateValue = (OpenApiDate) primitive;
|
||||
return dateValue.Value.ToString(CultureInfo.InvariantCulture);
|
||||
case PrimitiveType.DateTime:
|
||||
OpenApiDateTime dateTimeValue = (OpenApiDateTime) primitive;
|
||||
return dateTimeValue.Value.ToString();
|
||||
case PrimitiveType.Password:
|
||||
OpenApiPassword passwordValue = (OpenApiPassword) primitive;
|
||||
return passwordValue.Value;
|
||||
default:
|
||||
throw new NotImplementedException("This data example type is not supported yet!");
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetJsonValue(IOpenApiAny value)
|
||||
{
|
||||
StringBuilder builder = new StringBuilder();
|
||||
value.Write(new OpenApiJsonWriter(new StringWriter(builder)), OpenApiDocumentParser.Version);
|
||||
return builder.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
39
parser/Parser/OpenApiDocumentParser.cs
Normal file
39
parser/Parser/OpenApiDocumentParser.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Microsoft.OpenApi;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Microsoft.OpenApi.Readers;
|
||||
|
||||
namespace Parser
|
||||
{
|
||||
public static class OpenApiDocumentParser
|
||||
{
|
||||
public static OpenApiSpecVersion Version;
|
||||
public static OpenApiDocument ParseOpenApiDocument(string openApiDocFilePath)
|
||||
{
|
||||
OpenApiDocument openApiDocument;
|
||||
using (FileStream stream = File.Open(openApiDocFilePath, FileMode.Open))
|
||||
{
|
||||
openApiDocument = new OpenApiStreamReader().Read(stream, out var diagnostic);
|
||||
|
||||
StoreDocumentVersion(diagnostic.SpecificationVersion);
|
||||
PrintParsingErrors(diagnostic.Errors);
|
||||
}
|
||||
return openApiDocument;
|
||||
}
|
||||
|
||||
static void PrintParsingErrors(IList<OpenApiError> errors)
|
||||
{
|
||||
foreach (var openApiError in errors)
|
||||
{
|
||||
Console.WriteLine("WARNING: Following parsing error occurs: " + openApiError.Message);
|
||||
}
|
||||
}
|
||||
|
||||
static void StoreDocumentVersion(OpenApiSpecVersion version)
|
||||
{
|
||||
Version = version;
|
||||
}
|
||||
}
|
||||
}
|
||||
15
parser/Parser/Parser.csproj
Normal file
15
parser/Parser/Parser.csproj
Normal file
@@ -0,0 +1,15 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.OpenApi.Readers" Version="1.1.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Models\Models.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
48
parser/Parser/PrimitiveDataTypeExampleGenerator.cs
Normal file
48
parser/Parser/PrimitiveDataTypeExampleGenerator.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace Parser
|
||||
{
|
||||
// Data types for Open API 2 and OpenAPI 3 are basically the same:
|
||||
// https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md
|
||||
// https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md
|
||||
public static class PrimitiveDataTypeExampleGenerator
|
||||
{
|
||||
public static string GenerateExampleValueByType(string type, string format)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case "integer":
|
||||
return "42";
|
||||
case "number":
|
||||
return "42.0";
|
||||
case "boolean":
|
||||
return "True";
|
||||
case "string":
|
||||
{
|
||||
const string example = "example";
|
||||
switch (format)
|
||||
{
|
||||
case null:
|
||||
return example;
|
||||
case "byte":
|
||||
var plainTextBytes = Encoding.UTF8.GetBytes(example);
|
||||
return Encoding.Default.GetString(plainTextBytes);
|
||||
case "binary":
|
||||
return "01234567";
|
||||
case "date":
|
||||
return "2002-10-02";
|
||||
case "date-time":
|
||||
return "2002-10-02T10:00:00-05:00";
|
||||
case "password":
|
||||
return example;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
throw new NotImplementedException("Unrecognized value data type! Check the OpenAPI documentation for new types!");
|
||||
}
|
||||
}
|
||||
}
|
||||
59
parser/Parser/RequestParser.cs
Normal file
59
parser/Parser/RequestParser.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Models;
|
||||
|
||||
namespace Parser
|
||||
{
|
||||
public static class RequestParser
|
||||
{
|
||||
public static Request ParseRequest(KeyValuePair<OperationType, OpenApiOperation> operation)
|
||||
{
|
||||
var request = new Request(operation.Key.ToString())
|
||||
{
|
||||
Summary = operation.Value.Summary,
|
||||
BodyExample = GetBodyExample(operation.Value.RequestBody),
|
||||
BodySchema = GetBodySchema(operation.Value.RequestBody),
|
||||
UriAttributes = ParseUriAttributes(operation.Value),
|
||||
Responses = ParseResponses(operation.Value)
|
||||
};
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
static string GetBodyExample(OpenApiRequestBody body)
|
||||
{
|
||||
return body != null ? ExamplesParser.ParseExample(body.Content) : null;
|
||||
}
|
||||
|
||||
static Dictionary<string, object> GetBodySchema(OpenApiRequestBody body)
|
||||
{
|
||||
return body != null ? SchemaParser.ParseSchema(body.Content) : null;
|
||||
}
|
||||
|
||||
static List<UriAttribute> ParseUriAttributes(OpenApiOperation operation)
|
||||
{
|
||||
List<UriAttribute> attributes = new List<UriAttribute>();
|
||||
foreach (var parameter in operation.Parameters)
|
||||
{
|
||||
var attribute = AttributeParser.ParseAttribute(parameter);
|
||||
if (attribute != null)
|
||||
{
|
||||
attributes.Add(attribute);
|
||||
}
|
||||
}
|
||||
|
||||
return attributes;
|
||||
}
|
||||
|
||||
static List<Response> ParseResponses(OpenApiOperation operation)
|
||||
{
|
||||
List<Response> responses = new List<Response>();
|
||||
foreach (var openApiResponse in operation.Responses)
|
||||
{
|
||||
responses.Add(ResponseParser.ParseResponse(openApiResponse));
|
||||
}
|
||||
|
||||
return responses;
|
||||
}
|
||||
}
|
||||
}
|
||||
40
parser/Parser/ResponseParser.cs
Normal file
40
parser/Parser/ResponseParser.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Models;
|
||||
|
||||
namespace Parser
|
||||
{
|
||||
public static class ResponseParser
|
||||
{
|
||||
public static Response ParseResponse(KeyValuePair<string, OpenApiResponse> openApiResponse)
|
||||
{
|
||||
string example = null;
|
||||
if (openApiResponse.Value != null)
|
||||
example = ExamplesParser.ParseExample(openApiResponse.Value.Content);
|
||||
|
||||
var response = new Response
|
||||
{
|
||||
Example = example,
|
||||
StatusCode = ParseStatusCode(openApiResponse.Key)
|
||||
};
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
static int ParseStatusCode(string responseKey)
|
||||
{
|
||||
if (responseKey == "default")
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!int.TryParse(responseKey, out var statusCode))
|
||||
{
|
||||
throw new NotImplementedException("Provided status code is not supported: " + responseKey);
|
||||
}
|
||||
|
||||
return statusCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
78
parser/Parser/SchemaParser.cs
Normal file
78
parser/Parser/SchemaParser.cs
Normal file
@@ -0,0 +1,78 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.OpenApi.Models;
|
||||
|
||||
namespace Parser
|
||||
{
|
||||
public static class SchemaParser
|
||||
{
|
||||
public static Dictionary<string, object> ParseSchema(IDictionary<string, OpenApiMediaType> contentDict)
|
||||
{
|
||||
return contentDict.ContainsKey("application/json") ? ParseSchemaProperties(contentDict["application/json"].Schema) : null;
|
||||
}
|
||||
|
||||
static Dictionary<string, object> ParseSchemaProperties(OpenApiSchema schema)
|
||||
{
|
||||
Dictionary<string, object> parsedSchema = new Dictionary<string, object>();
|
||||
|
||||
if (schema.AdditionalPropertiesAllowed && schema.AdditionalProperties != null)
|
||||
{
|
||||
Dictionary<string, object> nestedSchema = ParseSchemaProperties(schema.AdditionalProperties);
|
||||
|
||||
// Create single object with string key: "AdditionalPropertyExample1" and with nested schema as it is in documentation
|
||||
// There can be multiple nested objects, but we want to reduce number of generated test cases
|
||||
parsedSchema.Add("AdditionalPropertyExample1", nestedSchema);
|
||||
}
|
||||
|
||||
if (schema.AllOf.Count > 0)
|
||||
{
|
||||
foreach (var openApiSchema in schema.AllOf)
|
||||
{
|
||||
Dictionary<string, object> nestedSchema = ParseSchemaProperties(openApiSchema);
|
||||
parsedSchema = MergeTwoDictionaries(nestedSchema, parsedSchema);
|
||||
}
|
||||
}
|
||||
|
||||
if (schema.OneOf.Count > 0)
|
||||
{
|
||||
Dictionary<string, object> nestedSchema = ParseSchemaProperties(schema.OneOf.First());
|
||||
parsedSchema = MergeTwoDictionaries(nestedSchema, parsedSchema);
|
||||
}
|
||||
|
||||
if (schema.AnyOf.Count > 0)
|
||||
{
|
||||
Dictionary<string, object> nestedSchema = ParseSchemaProperties(schema.AnyOf.First());
|
||||
parsedSchema = MergeTwoDictionaries(nestedSchema, parsedSchema);
|
||||
}
|
||||
|
||||
if (schema.Properties != null && schema.Properties.Count > 0)
|
||||
{
|
||||
foreach (var property in schema.Properties)
|
||||
{
|
||||
Dictionary<string, object> nestedSchema = ParseSchemaProperties(property.Value);
|
||||
parsedSchema.Add(property.Key, nestedSchema);
|
||||
}
|
||||
}
|
||||
else if (schema.Type != null && schema.Type.ToLower() == "array")
|
||||
{
|
||||
parsedSchema.Add("Type", schema.Type);
|
||||
Dictionary<string, object> arrayItemsSchema = ParseSchemaProperties(schema.Items);
|
||||
parsedSchema.Add("ArrayItemSchema", arrayItemsSchema);
|
||||
}
|
||||
else if (schema.Type != "object")
|
||||
{
|
||||
parsedSchema.Add("Title", schema.Title);
|
||||
parsedSchema.Add("Type", schema.Type);
|
||||
parsedSchema.Add("Format", schema.Format);
|
||||
parsedSchema.Add("Example", ContentParser.GetSingleExample(schema.Example));
|
||||
}
|
||||
|
||||
return parsedSchema;
|
||||
}
|
||||
|
||||
static Dictionary<string, object> MergeTwoDictionaries(Dictionary<string, object> first, Dictionary<string, object> second)
|
||||
{
|
||||
return new List<Dictionary<string, object>> { first, second }.SelectMany(dict => dict).ToDictionary(pair => pair.Key, pair => pair.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user