public void ThrowsInvalidOperationExceptionInCreatePredicateWhenInvalidArgumentsArePassed() { // Act and Assert var message1 = Assert.Throws <InvalidOperationException>(() => OpenApiFilterService.CreatePredicate(null, null)).Message; Assert.Equal("Either operationId(s),tag(s) or Postman collection need to be specified.", message1); var message2 = Assert.Throws <InvalidOperationException>(() => OpenApiFilterService.CreatePredicate("users.user.ListUser", "users.user")).Message; Assert.Equal("Cannot specify both operationIds and tags at the same time.", message2); }
public void ReturnFilteredOpenApiDocumentBasedOnOperationIdsAndTags(string operationIds, string tags, int expectedPathCount) { // Act var predicate = OpenApiFilterService.CreatePredicate(operationIds, tags); var subsetOpenApiDocument = OpenApiFilterService.CreateFilteredDocument(_openApiDocumentMock, predicate); // Assert Assert.NotNull(subsetOpenApiDocument); Assert.NotEmpty(subsetOpenApiDocument.Paths); Assert.Equal(expectedPathCount, subsetOpenApiDocument.Paths.Count); }
public void ThrowsExceptionWhenUrlsInCollectionAreMissingFromSourceDocument() { // Arrange var filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "UtilityFiles\\postmanCollection_ver1.json"); var fileInput = new FileInfo(filePath); var stream = fileInput.OpenRead(); // Act var requestUrls = OpenApiService.ParseJsonCollectionFile(stream, _logger); // Assert var message = Assert.Throws <ArgumentException>(() => OpenApiFilterService.CreatePredicate(requestUrls: requestUrls, source: _openApiDocumentMock)).Message; Assert.Equal("The urls in the Postman collection supplied could not be found.", message); }
public void ReturnFilteredOpenApiDocumentBasedOnPostmanCollection() { // Arrange var filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "UtilityFiles\\postmanCollection_ver2.json"); var fileInput = new FileInfo(filePath); var stream = fileInput.OpenRead(); // Act var requestUrls = OpenApiService.ParseJsonCollectionFile(stream, _logger); var predicate = OpenApiFilterService.CreatePredicate(requestUrls: requestUrls, source: _openApiDocumentMock); var subsetOpenApiDocument = OpenApiFilterService.CreateFilteredDocument(_openApiDocumentMock, predicate); // Assert Assert.NotNull(subsetOpenApiDocument); Assert.NotEmpty(subsetOpenApiDocument.Paths); Assert.Equal(3, subsetOpenApiDocument.Paths.Count); }
public static void ProcessOpenApiDocument( string input, FileInfo output, OpenApiSpecVersion version, OpenApiFormat format, string filterByOperationIds, string filterByTags, bool inline, bool resolveExternal) { if (string.IsNullOrEmpty(input)) { throw new ArgumentNullException(nameof(input)); } if (output == null) { throw new ArgumentException(nameof(output)); } if (output.Exists) { throw new IOException("The file you're writing to already exists. Please input a new output path."); } var stream = GetStream(input); var result = new OpenApiStreamReader(new OpenApiReaderSettings { ReferenceResolution = resolveExternal ? ReferenceResolutionSetting.ResolveAllReferences : ReferenceResolutionSetting.ResolveLocalReferences, RuleSet = ValidationRuleSet.GetDefaultRuleSet() } ).ReadAsync(stream).GetAwaiter().GetResult(); OpenApiDocument document; document = result.OpenApiDocument; // Check if filter options are provided, then execute if (!string.IsNullOrEmpty(filterByOperationIds) && !string.IsNullOrEmpty(filterByTags)) { throw new InvalidOperationException("Cannot filter by operationIds and tags at the same time."); } if (!string.IsNullOrEmpty(filterByOperationIds)) { var predicate = OpenApiFilterService.CreatePredicate(operationIds: filterByOperationIds); document = OpenApiFilterService.CreateFilteredDocument(document, predicate); } if (!string.IsNullOrEmpty(filterByTags)) { var predicate = OpenApiFilterService.CreatePredicate(tags: filterByTags); document = OpenApiFilterService.CreateFilteredDocument(document, predicate); } var context = result.OpenApiDiagnostic; if (context.Errors.Count > 0) { var errorReport = new StringBuilder(); foreach (var error in context.Errors) { errorReport.AppendLine(error.ToString()); } throw new ArgumentException(string.Join(Environment.NewLine, context.Errors.Select(e => e.Message).ToArray())); } using var outputStream = output?.Create(); var textWriter = outputStream != null ? new StreamWriter(outputStream) : Console.Out; var settings = new OpenApiWriterSettings() { ReferenceInline = inline ? ReferenceInlineSetting.InlineLocalReferences : ReferenceInlineSetting.DoNotInlineReferences }; IOpenApiWriter writer = format switch { OpenApiFormat.Json => new OpenApiJsonWriter(textWriter, settings), OpenApiFormat.Yaml => new OpenApiYamlWriter(textWriter, settings), _ => throw new ArgumentException("Unknown format"), }; document.Serialize(writer, version); textWriter.Flush(); }
public static async void ProcessOpenApiDocument( string openapi, FileInfo output, OpenApiSpecVersion?version, OpenApiFormat?format, LogLevel loglevel, bool inline, bool resolveexternal, string filterbyoperationids, string filterbytags, string filterbycollection ) { var logger = ConfigureLoggerInstance(loglevel); try { if (string.IsNullOrEmpty(openapi)) { throw new ArgumentNullException(nameof(openapi)); } } catch (ArgumentNullException ex) { logger.LogError(ex.Message); return; } try { if (output == null) { throw new ArgumentException(nameof(output)); } } catch (ArgumentException ex) { logger.LogError(ex.Message); return; } try { if (output.Exists) { throw new IOException("The file you're writing to already exists. Please input a new file path."); } } catch (IOException ex) { logger.LogError(ex.Message); return; } var stream = await GetStream(openapi, logger); // Parsing OpenAPI file var stopwatch = new Stopwatch(); stopwatch.Start(); logger.LogTrace("Parsing OpenApi file"); var result = new OpenApiStreamReader(new OpenApiReaderSettings { ReferenceResolution = resolveexternal ? ReferenceResolutionSetting.ResolveAllReferences : ReferenceResolutionSetting.ResolveLocalReferences, RuleSet = ValidationRuleSet.GetDefaultRuleSet() } ).ReadAsync(stream).GetAwaiter().GetResult(); var document = result.OpenApiDocument; stopwatch.Stop(); var context = result.OpenApiDiagnostic; if (context.Errors.Count > 0) { var errorReport = new StringBuilder(); foreach (var error in context.Errors) { errorReport.AppendLine(error.ToString()); } logger.LogError($"{stopwatch.ElapsedMilliseconds}ms: OpenApi Parsing errors {string.Join(Environment.NewLine, context.Errors.Select(e => e.Message).ToArray())}"); } else { logger.LogTrace("{timestamp}ms: Parsed OpenApi successfully. {count} paths found.", stopwatch.ElapsedMilliseconds, document.Paths.Count); } Func <string, OperationType?, OpenApiOperation, bool> predicate; // Check if filter options are provided, then slice the OpenAPI document if (!string.IsNullOrEmpty(filterbyoperationids) && !string.IsNullOrEmpty(filterbytags)) { throw new InvalidOperationException("Cannot filter by operationIds and tags at the same time."); } if (!string.IsNullOrEmpty(filterbyoperationids)) { logger.LogTrace("Creating predicate based on the operationIds supplied."); predicate = OpenApiFilterService.CreatePredicate(operationIds: filterbyoperationids); logger.LogTrace("Creating subset OpenApi document."); document = OpenApiFilterService.CreateFilteredDocument(document, predicate); } if (!string.IsNullOrEmpty(filterbytags)) { logger.LogTrace("Creating predicate based on the tags supplied."); predicate = OpenApiFilterService.CreatePredicate(tags: filterbytags); logger.LogTrace("Creating subset OpenApi document."); document = OpenApiFilterService.CreateFilteredDocument(document, predicate); } if (!string.IsNullOrEmpty(filterbycollection)) { var fileStream = await GetStream(filterbycollection, logger); var requestUrls = ParseJsonCollectionFile(fileStream, logger); logger.LogTrace("Creating predicate based on the paths and Http methods defined in the Postman collection."); predicate = OpenApiFilterService.CreatePredicate(requestUrls: requestUrls, source: document); logger.LogTrace("Creating subset OpenApi document."); document = OpenApiFilterService.CreateFilteredDocument(document, predicate); } logger.LogTrace("Creating a new file"); using var outputStream = output?.Create(); var textWriter = outputStream != null ? new StreamWriter(outputStream) : Console.Out; var settings = new OpenApiWriterSettings() { ReferenceInline = inline ? ReferenceInlineSetting.InlineLocalReferences : ReferenceInlineSetting.DoNotInlineReferences }; var openApiFormat = format ?? GetOpenApiFormat(openapi, logger); var openApiVersion = version ?? result.OpenApiDiagnostic.SpecificationVersion; IOpenApiWriter writer = openApiFormat switch { OpenApiFormat.Json => new OpenApiJsonWriter(textWriter, settings), OpenApiFormat.Yaml => new OpenApiYamlWriter(textWriter, settings), _ => throw new ArgumentException("Unknown format"), }; logger.LogTrace("Serializing to OpenApi document using the provided spec version and writer"); stopwatch.Start(); document.Serialize(writer, openApiVersion); stopwatch.Stop(); logger.LogTrace($"Finished serializing in {stopwatch.ElapsedMilliseconds}ms"); textWriter.Flush(); }