public void ReadDefinition_WithHostAndTwoSchemes_BaseAddressesHasTwoEntries() { string json = @"{ ""swagger"": ""2.0"", ""info"": { ""version"": ""v1"" }, ""host"": ""localhost"", ""schemes"": [ ""https"", ""http"" ], ""paths"": { } }"; OpenApiDotNetApiDefinitionReader swaggerV2ApiDefinitionReader = new OpenApiDotNetApiDefinitionReader(); ApiDefinitionParseResult result = swaggerV2ApiDefinitionReader.ReadDefinition(json, new Uri("http://localhost/swagger.json")); Assert.NotNull(result.ApiDefinition?.BaseAddresses); Assert.Equal(2, result.ApiDefinition.BaseAddresses.Count); Assert.Equal("https://localhost/", result.ApiDefinition.BaseAddresses[0].Url.ToString(), StringComparer.Ordinal); Assert.Equal("http://localhost/", result.ApiDefinition.BaseAddresses[1].Url.ToString(), StringComparer.Ordinal); }
public void ReadDefinition_WithHostAndNoScheme_BaseAddressesHasOneEntryWithSchemeFromSourceUri() { string json = @"{ ""swagger"": ""2.0"", ""info"": { ""version"": ""v1"" }, ""host"": ""localhost"", ""paths"": { } }"; OpenApiDotNetApiDefinitionReader swaggerV2ApiDefinitionReader = new OpenApiDotNetApiDefinitionReader(); ApiDefinitionParseResult result = swaggerV2ApiDefinitionReader.ReadDefinition(json, new Uri("https://localhost/swagger.json")); Assert.NotNull(result.ApiDefinition?.BaseAddresses); Assert.Single(result.ApiDefinition.BaseAddresses); Assert.Equal("https://localhost/", result.ApiDefinition.BaseAddresses[0].Url.ToString(), StringComparer.Ordinal); result = swaggerV2ApiDefinitionReader.ReadDefinition(json, new Uri("http://localhost/swagger.json")); Assert.NotNull(result.ApiDefinition?.BaseAddresses); Assert.Single(result.ApiDefinition.BaseAddresses); Assert.Equal("http://localhost/", result.ApiDefinition.BaseAddresses[0].Url.ToString(), StringComparer.Ordinal); }
public void ReadDefinition_WithRelativeServer_BaseAddressesCorrectEntry() { string json = @"{ ""openapi"": ""3.0.0"", ""info"": { ""version"": ""v1"" }, ""servers"": [ { ""url"": ""/api/v2"", ""description"": ""First Server Address"" } ], ""paths"": { ""/pets"": { } } }"; OpenApiDotNetApiDefinitionReader openApiV3ApiDefinitionReader = new OpenApiDotNetApiDefinitionReader(); ApiDefinitionParseResult result = openApiV3ApiDefinitionReader.ReadDefinition(json, new Uri("https://localhost/swagger.json")); Assert.NotNull(result.ApiDefinition?.BaseAddresses); Assert.Single(result.ApiDefinition.BaseAddresses); Assert.Equal("https://localhost/api/v2/", result.ApiDefinition.BaseAddresses[0].Url.ToString()); Assert.Equal("First Server Address", result.ApiDefinition.BaseAddresses[0].Description); }
public void ReadMetadata_WithNoResponses_ReturnsApiDefinition() { string json = @"{ ""openapi"": ""3.0.0"", ""paths"": { ""/pets"": { ""post"": { ""summary"": ""Create a pet"", ""operationId"": ""createPets"", ""requestBody"": { ""content"": { } } } } } }"; OpenApiDotNetApiDefinitionReader openApiV3ApiDefinitionReader = new OpenApiDotNetApiDefinitionReader(); ApiDefinitionParseResult result = openApiV3ApiDefinitionReader.ReadDefinition(json, null); Assert.NotNull(result.ApiDefinition?.DirectoryStructure); Assert.Single(result.ApiDefinition.DirectoryStructure.DirectoryNames); Assert.Equal("pets", result.ApiDefinition.DirectoryStructure.DirectoryNames.Single()); IDirectoryStructure subDirectory = result.ApiDefinition.DirectoryStructure.TraverseTo("/pets"); Assert.Single(subDirectory.RequestInfo.Methods); Assert.Contains("Post", subDirectory.RequestInfo.Methods, StringComparer.Ordinal); }
public void ReadMetadata_WithValidInput_ReturnsApiDefinition() { string json = @"{ ""openapi"": ""3.0.0"", ""paths"": { ""/pets"": { ""get"": { ""summary"": ""List all pets"", ""operationId"": ""listPets"", ""parameters"": [ { ""name"": ""limit"", ""in"": ""query"", ""required"": false, ""schema"": { ""type"": ""integer"", ""format"": ""int32"" } } ], ""responses"": { ""200"": { ""description"": ""An paged array of pets"" } } }, ""post"": { ""summary"": ""Create a pet"", ""operationId"": ""createPets"", ""responses"": { ""201"": { ""description"": ""Null response"" } }, ""requestBody"": { ""content"": { } } } } } }"; OpenApiDotNetApiDefinitionReader openApiV3ApiDefinitionReader = new OpenApiDotNetApiDefinitionReader(); ApiDefinitionParseResult result = openApiV3ApiDefinitionReader.ReadDefinition(json, null); Assert.NotNull(result.ApiDefinition?.DirectoryStructure); Assert.Single(result.ApiDefinition.DirectoryStructure.DirectoryNames); Assert.Equal("pets", result.ApiDefinition.DirectoryStructure.DirectoryNames.Single()); IDirectoryStructure subDirectory = result.ApiDefinition.DirectoryStructure.TraverseTo("/pets"); Assert.Equal(2, subDirectory.RequestInfo.Methods.Count); Assert.Contains("Get", subDirectory.RequestInfo.Methods, StringComparer.Ordinal); Assert.Contains("Post", subDirectory.RequestInfo.Methods, StringComparer.Ordinal); }
public async Task CanHandle_RealOpenApiDescriptions_ReturnsNotNull(string resourcePath) { // Arrange string content = await GetResourceContent(resourcePath); OpenApiDotNetApiDefinitionReader apiDefinitionReader = new(); // Act ApiDefinitionParseResult actual = apiDefinitionReader.CanHandle(content); // Assert Assert.True(actual.Success); }
public async Task ReadDefinition_RealOpenApiDescriptions_ReturnsExpectedDocument(string resourcePath, ApiDefinition expected) { // Arrange string content = await GetResourceContent(resourcePath); OpenApiDotNetApiDefinitionReader apiDefinitionReader = new(); // Act ApiDefinitionParseResult actual = apiDefinitionReader.ReadDefinition(content, null); // Assert AssertDefinition(expected, actual.ApiDefinition); }
public void ReadMetadata_WithSpecifiedMethodName_ReturnsApiDefinitionWithCorrectNumberOfRequestMethods(string method, bool shouldHaveRequest) { // The method must be lowercase to be valid in the json string methodForJson = method.ToLower(); string json = @"{ ""openapi"": ""3.0.0"", ""info"": { ""title"": ""OpenAPI v3 Spec"", ""version"": ""v1"" }, ""paths"": { ""/pets"": { """ + methodForJson + @""": { ""summary"": ""Do something"", ""operationId"": ""doSomething"", ""responses"": { ""200"": { ""description"": ""Null response"" } }, ""requestBody"": { ""description"": ""A Request Body"", ""required"": false } } } } }"; OpenApiDotNetApiDefinitionReader openApiV3ApiDefinitionReader = new OpenApiDotNetApiDefinitionReader(); ApiDefinitionParseResult result = openApiV3ApiDefinitionReader.ReadDefinition(json, null); Assert.NotNull(result.ApiDefinition?.DirectoryStructure); Assert.Single(result.ApiDefinition.DirectoryStructure.DirectoryNames); Assert.Equal("pets", result.ApiDefinition.DirectoryStructure.DirectoryNames.Single()); IDirectoryStructure subDirectory = result.ApiDefinition.DirectoryStructure.TraverseTo("/pets"); if (shouldHaveRequest) { Assert.Single(subDirectory.RequestInfo.Methods); Assert.Contains(method, subDirectory.RequestInfo.Methods, StringComparer.OrdinalIgnoreCase); } else { Assert.Null(subDirectory.RequestInfo); } }
public void Read_WithJObjectFormatNotSupportedByAnyExistingReader_ReturnsNull() { string json = @"{ ""info"": { ""version"": ""v1"", ""title"": ""My API"" } }"; ApiDefinitionReader apiDefinitionReader = new ApiDefinitionReader(); ApiDefinitionParseResult result = apiDefinitionReader.Read(json, null); Assert.False(result.Success); }
public void ReadMetadata_WithNoMethods_ReturnsApiDefinitionWithStructure() { string json = @"{ ""openapi"": ""3.0.0"", ""paths"": { ""/pets"": { } } }"; OpenApiDotNetApiDefinitionReader openApiV3ApiDefinitionReader = new OpenApiDotNetApiDefinitionReader(); ApiDefinitionParseResult result = openApiV3ApiDefinitionReader.ReadDefinition(json, null); Assert.NotNull(result.ApiDefinition?.DirectoryStructure); }
public void ReadMetadata_WithNoPaths_ReturnsApiDefinitionWithNoDirectories() { string json = @"{ ""swagger"": ""2.0"", ""info"": { ""version"": ""v1"" } }"; OpenApiDotNetApiDefinitionReader swaggerV2ApiDefinitionReader = new OpenApiDotNetApiDefinitionReader(); ApiDefinitionParseResult result = swaggerV2ApiDefinitionReader.ReadDefinition(json, null); Assert.NotNull(result.ApiDefinition?.DirectoryStructure); Assert.Empty(result.ApiDefinition.DirectoryStructure.DirectoryNames); }
public void SetupApiDefinition(HttpState programState) { if (SwaggerDocument is not null && SwaggerUri is not null) { ApiDefinitionReader reader = new ApiDefinitionReader(); ApiDefinitionParseResult parseResult = reader.Read(SwaggerDocument, SwaggerUri); if (parseResult.Success) { programState.ApiDefinition = parseResult.ApiDefinition; if (programState.ApiDefinition is not null) { programState.SwaggerEndpoint = SwaggerUri; } } } }
public void ReadMetadata_WithNoPaths_ReturnsEmptyDirectoryStructure() { string json = @"{ ""openapi"": ""3.0.0"", ""info"": { ""version"": ""v1"" } }"; OpenApiDotNetApiDefinitionReader openApiV3ApiDefinitionReader = new OpenApiDotNetApiDefinitionReader(); ApiDefinitionParseResult result = openApiV3ApiDefinitionReader.ReadDefinition(json, null); Assert.NotNull(result.ApiDefinition?.DirectoryStructure); Assert.Empty(result.ApiDefinition.DirectoryStructure.DirectoryNames); }
public void CanHandle_WithNoSwaggerVersionKeyInDocument_ReturnsFalse() { string json = @"{ ""info"": { ""title"": ""OpenAPI v? Spec"", ""version"": ""v1"" }, ""paths"": { } }"; OpenApiDotNetApiDefinitionReader swaggerV2ApiDefinitionReader = new OpenApiDotNetApiDefinitionReader(); ApiDefinitionParseResult result = swaggerV2ApiDefinitionReader.CanHandle(json); Assert.False(result.Success); }
public void CanHandle_WithMissingInfoAndPaths_ReturnsValidationMessages() { // Arrange string json = @" { ""openapi"": ""3.0.0"" } "; OpenApiDotNetApiDefinitionReader apiDefinitionReader = new(); // Act ApiDefinitionParseResult result = apiDefinitionReader.CanHandle(json); // Assert Assert.True(result.Success); Assert.NotEqual(0, result.ValidationMessages.Count); }
public void ReadMetadata_WithContentAndMultipleContentTypes_ReturnsApiDefinitionWithContentTypes() { string json = @"{ ""openapi"": ""3.0.0"", ""paths"": { ""/pets"": { ""post"": { ""summary"": ""Create a pet"", ""operationId"": ""createPets"", ""responses"": { ""201"": { ""description"": ""Null response"" } }, ""requestBody"": { ""description"": ""A Request Body"", ""required"": false, ""content"": { ""application/json"": { }, ""text/plain"": { } } } } } } }"; OpenApiDotNetApiDefinitionReader openApiV3ApiDefinitionReader = new OpenApiDotNetApiDefinitionReader(); ApiDefinitionParseResult result = openApiV3ApiDefinitionReader.ReadDefinition(json, null); Assert.NotNull(result.ApiDefinition?.DirectoryStructure); Assert.Single(result.ApiDefinition.DirectoryStructure.DirectoryNames); Assert.Equal("pets", result.ApiDefinition.DirectoryStructure.DirectoryNames.Single()); IDirectoryStructure subDirectory = result.ApiDefinition.DirectoryStructure.TraverseTo("/pets"); Assert.Single(subDirectory.RequestInfo.Methods); Assert.Contains("Post", subDirectory.RequestInfo.Methods, StringComparer.Ordinal); Assert.Equal(2, subDirectory.RequestInfo.ContentTypesByMethod["post"].Count); Assert.Contains("application/json", subDirectory.RequestInfo.ContentTypesByMethod["post"]); Assert.Contains("text/plain", subDirectory.RequestInfo.ContentTypesByMethod["post"]); }
public void ReadMetadata_WithNoResponses_ReturnsApiDefinitionWithNoRequestInfo() { string json = @"{ ""openapi"": ""3.0.0"", ""paths"": { ""/pets"": { } } }"; OpenApiDotNetApiDefinitionReader openApiV3ApiDefinitionReader = new OpenApiDotNetApiDefinitionReader(); ApiDefinitionParseResult result = openApiV3ApiDefinitionReader.ReadDefinition(json, null); IDirectoryStructure subDirectory = result.ApiDefinition.DirectoryStructure.TraverseTo("/pets"); Assert.Null(subDirectory.RequestInfo); }
public void CanHandle_WithValidOpenApiVersionInDocument_ReturnsTrue() { string json = @"{ ""openapi"": ""3.0.0"", ""info"": { ""title"": ""OpenAPI v3 Spec"", ""version"": ""v1"" }, ""paths"": { } }"; OpenApiDotNetApiDefinitionReader openApiV3ApiDefinitionReader = new OpenApiDotNetApiDefinitionReader(); ApiDefinitionParseResult result = openApiV3ApiDefinitionReader.CanHandle(json); Assert.True(result.Success); }
public void ReadDefinition_WithNoHost_BaseAddressesIsEmpty() { string json = @"{ ""swagger"": ""2.0"", ""info"": { ""version"": ""v1"" }, ""paths"": { } }"; OpenApiDotNetApiDefinitionReader swaggerV2ApiDefinitionReader = new OpenApiDotNetApiDefinitionReader(); ApiDefinitionParseResult result = swaggerV2ApiDefinitionReader.ReadDefinition(json, new Uri("http://localhost/swagger.json")); Assert.NotNull(result.ApiDefinition?.BaseAddresses); Assert.Empty(result.ApiDefinition.BaseAddresses); }
public void CanHandle_WithOpenApiVersionGreaterThanThree_ReturnsFalse() { string json = @"{ ""openapi"": ""4.0.0"", ""info"": { ""title"": ""OpenAPI v4 Spec"", ""version"": ""v1"" }, ""paths"": { } }"; OpenApiDotNetApiDefinitionReader openApiV3ApiDefinitionReader = new OpenApiDotNetApiDefinitionReader(); ApiDefinitionParseResult result = openApiV3ApiDefinitionReader.CanHandle(json); Assert.False(result.Success); }
public void ReadMetadata_WithNoRequestMethods_ReturnsApiDefinitionWithStructure() { string json = @"{ ""swagger"": ""2.0"", ""info"": { ""version"": ""v1"" }, ""paths"": { ""/api/Employees"": { } } }"; OpenApiDotNetApiDefinitionReader swaggerV2ApiDefinitionReader = new OpenApiDotNetApiDefinitionReader(); ApiDefinitionParseResult result = swaggerV2ApiDefinitionReader.ReadDefinition(json, null); Assert.NotNull(result.ApiDefinition?.DirectoryStructure); }
public void ReadMetadata_WithNoContent_ReturnsApiDefinitionWithRequestMethodButNoContentTypes() { string json = @"{ ""openapi"": ""3.0.0"", ""info"": { ""title"": ""OpenAPI v3 Spec"", ""version"": ""v1"" }, ""paths"": { ""/pets"": { ""post"": { ""summary"": ""Create a pet"", ""operationId"": ""createPets"", ""responses"": { ""201"": { ""description"": ""Null response"" } }, ""requestBody"": { ""description"": ""A Request Body"", ""required"": false } } } } }"; OpenApiDotNetApiDefinitionReader openApiV3ApiDefinitionReader = new OpenApiDotNetApiDefinitionReader(); ApiDefinitionParseResult result = openApiV3ApiDefinitionReader.ReadDefinition(json, null); Assert.NotNull(result.ApiDefinition?.DirectoryStructure); Assert.Single(result.ApiDefinition.DirectoryStructure.DirectoryNames); Assert.Equal("pets", result.ApiDefinition.DirectoryStructure.DirectoryNames.Single()); IDirectoryStructure subDirectory = result.ApiDefinition.DirectoryStructure.TraverseTo("/pets"); Assert.Single(subDirectory.RequestInfo.Methods); Assert.Contains("Post", subDirectory.RequestInfo.Methods, StringComparer.Ordinal); Assert.DoesNotContain("post", subDirectory.RequestInfo.ContentTypesByMethod.Keys, StringComparer.Ordinal); }
public void ReadDefinition_WithNoServers_BaseAddressesIsEmpty() { string json = @"{ ""openapi"": ""3.0.0"", ""info"": { ""version"": ""v1"" }, ""paths"": { ""/pets"": { } } }"; OpenApiDotNetApiDefinitionReader openApiV3ApiDefinitionReader = new OpenApiDotNetApiDefinitionReader(); ApiDefinitionParseResult result = openApiV3ApiDefinitionReader.ReadDefinition(json, null); Assert.NotNull(result.ApiDefinition?.BaseAddresses); Assert.Empty(result.ApiDefinition.BaseAddresses); }
public void ReadDefinition_WithRequestBody_SchemaIsIncluded() { string contentType = "application/json"; string json = @"{ ""openapi"": ""3.0.0"", ""info"": { ""version"": ""v1"" }, ""paths"": { ""/pets"": { ""post"": { ""requestBody"": { ""content"": { """ + contentType + @""": { ""schema"": { ""type"": ""object"", ""properties"": { ""date"": { ""type"": ""string"", ""format"": ""date-time"" } } } } } } } } } }"; OpenApiDotNetApiDefinitionReader openApiV3ApiDefinitionReader = new OpenApiDotNetApiDefinitionReader(); ApiDefinitionParseResult result = openApiV3ApiDefinitionReader.ReadDefinition(json, new Uri("https://localhost/swagger.json")); IDirectoryStructure pets = result.ApiDefinition.DirectoryStructure.TraverseTo("pets"); string requestBody = pets.RequestInfo.GetRequestBodyForContentType(ref contentType, "post"); Assert.NotNull(requestBody); }
public void RegisterReader_AddNewReader_VerifyReadReturnsApiDefinitionWithStructure() { string json = @"{ ""fakeApi"": ""1.0.0"", ""info"": { ""version"": ""v1"" } }"; ApiDefinition apiDefinition = new ApiDefinition() { DirectoryStructure = new DirectoryStructure(null) }; ApiDefinitionReaderStub apiDefinitionReaderStub = new ApiDefinitionReaderStub(apiDefinition); ApiDefinitionReader reader = new ApiDefinitionReader(); reader.RegisterReader(apiDefinitionReaderStub); ApiDefinitionParseResult result = reader.Read(json, null); Assert.Same(apiDefinition, result.ApiDefinition); }
public void ReadDefinition_WithTwoServers_BaseAddressesHasTwoEntries() { string json = @"{ ""openapi"": ""3.0.0"", ""info"": { ""version"": ""v1"" }, ""servers"": [ { ""url"": ""https://petstore.swagger.io/"", ""description"": ""Production Server Address"" }, { ""url"": ""https://localhost/"", ""description"": ""Local Development Server Address"" } ], ""paths"": { ""/pets"": { } } }"; OpenApiDotNetApiDefinitionReader openApiV3ApiDefinitionReader = new OpenApiDotNetApiDefinitionReader(); ApiDefinitionParseResult result = openApiV3ApiDefinitionReader.ReadDefinition(json, null); Assert.NotNull(result.ApiDefinition?.BaseAddresses); Assert.Equal(2, result.ApiDefinition.BaseAddresses.Count); Assert.Equal("https://petstore.swagger.io/", result.ApiDefinition.BaseAddresses[0].Url.ToString()); Assert.Equal("Production Server Address", result.ApiDefinition.BaseAddresses[0].Description); Assert.Equal("https://localhost/", result.ApiDefinition.BaseAddresses[1].Url.ToString()); Assert.Equal("Local Development Server Address", result.ApiDefinition.BaseAddresses[1].Description); }
public void ReadMetadata_WithValidInput_ReturnsApiDefinition() { string json = @"{ ""swagger"": ""2.0"", ""info"": { ""version"": ""v1"" }, ""paths"": { ""/api/Employees"": { ""get"": { ""tags"": [ ""Employees"" ], ""operationId"": ""GetEmployee"", ""consumes"": [], ""produces"": [ ""text/plain"" ], ""parameters"": [], ""responses"": { ""200"": { ""description"": ""Success"" } } }, ""post"": { ""tags"": [ ""Employees"" ], ""operationId"": ""put"", ""consumes"": [], ""produces"": [ ""text/plain"" ], ""parameters"": [ { ""name"": ""id"", ""in"": ""path"" } ], ""responses"": { ""200"": { ""description"": ""Success"" } } } } } }"; OpenApiDotNetApiDefinitionReader swaggerV2ApiDefinitionReader = new OpenApiDotNetApiDefinitionReader(); ApiDefinitionParseResult result = swaggerV2ApiDefinitionReader.ReadDefinition(json, null); Assert.NotNull(result.ApiDefinition?.DirectoryStructure); Assert.Single(result.ApiDefinition.DirectoryStructure.DirectoryNames); Assert.Equal("api", result.ApiDefinition.DirectoryStructure.DirectoryNames.Single()); IDirectoryStructure subDirectory = result.ApiDefinition.DirectoryStructure.TraverseTo("/api/Employees"); Assert.Equal(2, subDirectory.RequestInfo.Methods.Count); Assert.Contains("Get", subDirectory.RequestInfo.Methods, StringComparer.Ordinal); Assert.Contains("Post", subDirectory.RequestInfo.Methods, StringComparer.Ordinal); }
private async Task <string?> GetSwaggerDocAsync(HttpClient client, Uri uri, CancellationToken cancellationToken) { try { WriteVerbose(string.Format(Resources.Strings.ApiConnection_Logging_Checking, uri)); HttpResponseMessage?response = await client.GetAsync(uri, cancellationToken).ConfigureAwait(false); if (cancellationToken.IsCancellationRequested) { _logger.WriteLine(Resources.Strings.ApiConnection_Logging_Cancelled.SetColor(_httpState.ErrorColor)); return(null); } if (response.IsSuccessStatusCode) { WriteLineVerbose(Resources.Strings.ApiConnection_Logging_Found.SetColor(AllowedColors.BoldGreen)); #if NET5_0 string responseString = await response.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false); #else string responseString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); #endif WriteVerbose(Resources.Strings.ApiConnection_Logging_Parsing); ApiDefinitionReader reader = new ApiDefinitionReader(); ApiDefinitionParseResult result = reader.CanHandle(responseString); if (result.Success) { if (result.ValidationMessages.Count == 0) { WriteLineVerbose(Resources.Strings.ApiConnection_Logging_Successful.SetColor(AllowedColors.BoldGreen)); } else { WriteLineVerbose(Resources.Strings.ApiConnection_Logging_SuccessfulWithWarnings.SetColor(_httpState.WarningColor)); foreach (string validationMessage in result.ValidationMessages) { WriteLineVerbose(validationMessage.SetColor(_httpState.WarningColor)); } } return(responseString); } else { WriteLineVerbose(Resources.Strings.ApiConnection_Logging_Failed.SetColor(_httpState.ErrorColor)); return(null); } } else { int statusCode = (int)response.StatusCode; string statusCodeDescription = response.StatusCode.ToString(); WriteLineVerbose($"{statusCode} {statusCodeDescription}".SetColor(_httpState.ErrorColor)); return(null); } } catch (Exception e) { WriteLineVerbose(e.Message.SetColor(_httpState.ErrorColor)); return(null); } finally { WriteLineVerbose(); } }