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);
        }
Beispiel #5
0
        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();
        }