public async Task SwaggerUIIndex_ServesAnEmbeddedVersionOfTheSwaggerUI()
        {
            var client = new TestSite(typeof(Basic.Startup)).BuildClient();

            var indexResponse = await client.GetAsync("/"); // Basic is configured to serve UI at root

            var jsBundleResponse = await client.GetAsync("/swagger-ui.js");

            var cssBundleResponse = await client.GetAsync("/swagger-ui.css");

            var jsEdgeFixResponse = await client.GetAsync("/edge-fix.js");

            var jsConfigResponse = await client.GetAsync("/config.js");

            var cssStyleResponse = await client.GetAsync("/style.css");

            var indexContent = await indexResponse.Content.ReadAsStringAsync();

            var jsConfigContent = await jsConfigResponse.Content.ReadAsStringAsync();

            Assert.Contains("{'urls':[{'url':'/swagger/v1/swagger.json','name':'V1 Docs'}],'validatorUrl':null}".Replace("'", "\""), indexContent);
            Assert.Contains("SwaggerUIBundle", jsConfigContent);
            Assert.Equal(HttpStatusCode.OK, jsBundleResponse.StatusCode);
            Assert.Equal(HttpStatusCode.OK, cssBundleResponse.StatusCode);
            Assert.Equal(HttpStatusCode.OK, jsEdgeFixResponse.StatusCode);
            Assert.Equal(HttpStatusCode.OK, jsConfigResponse.StatusCode);
            Assert.Equal(HttpStatusCode.OK, cssStyleResponse.StatusCode);
        }
        public async Task SwaggerEndpoint_ReturnsCorrectPriceExample_ForDifferentCultures(string culture)
        {
            var testSite = new TestSite(typeof(Basic.Startup));
            var client   = testSite.BuildClient();

            var swaggerResponse = await client.GetAsync($"/swagger/v1/swagger.json?culture={culture}");

            swaggerResponse.EnsureSuccessStatusCode();
            var contentStream = await swaggerResponse.Content.ReadAsStreamAsync();

            var currentCulture = CultureInfo.CurrentCulture;

            CultureInfo.CurrentCulture = CultureInfo.InvariantCulture;
            try
            {
                var openApiDocument = new OpenApiStreamReader().Read(contentStream, out OpenApiDiagnostic diagnostic);
                var example         = openApiDocument.Components.Schemas["Product"].Example as OpenApiObject;
                var price           = (example["price"] as OpenApiDouble);
                Assert.NotNull(price);
                Assert.Equal(14.37, price.Value);
            }
            finally
            {
                CultureInfo.CurrentCulture = currentCulture;
            }
        }
Example #3
0
        public async Task RoutePrefix_RedirectsSubAppRelativeIndexUrl()
        {
            var client   = new TestSite(typeof(SubApp.Startup)).BuildClient();
            var response = await client.GetAsync("/subapp");

            Assert.Equal(HttpStatusCode.MovedPermanently, response.StatusCode);
            Assert.Equal("subapp/index.html", response.Headers.Location.ToString());
        }
        public async Task SwaggerUIIndex_RedirectsToTrailingSlash_IfNotProvided()
        {
            var client = new TestSite(typeof(CustomUIConfig.Startup)).BuildClient();

            var response = await client.GetAsync("/swagger");

            Assert.Equal(HttpStatusCode.MovedPermanently, response.StatusCode);
            Assert.Equal("swagger/", response.Headers.Location.ToString());
        }
Example #5
0
        public async Task RoutePrefix_RedirectsToIndexUrl()
        {
            var client = new TestSite(typeof(CustomUIConfig.Startup)).BuildClient();

            var response = await client.GetAsync("/swagger");

            Assert.Equal(HttpStatusCode.MovedPermanently, response.StatusCode);
            Assert.Equal("http://localhost/swagger/index.html", response.Headers.Location.ToString());
        }
        public async Task SwaggerEndpoint_ReturnsNotFound_IfUnknownSwaggerDocument()
        {
            var testSite = new TestSite(typeof(Basic.Startup));
            var client   = testSite.BuildClient();

            var swaggerResponse = await client.GetAsync("/swagger/v2/swagger.json");

            Assert.Equal(System.Net.HttpStatusCode.NotFound, swaggerResponse.StatusCode);
        }
        public async Task SwaggerUIIndex_ServesCustomIndexHtml_IfConfigured()
        {
            var client = new TestSite(typeof(CustomUIIndex.Startup)).BuildClient();

            var response = await client.GetAsync("/swagger/");

            var content = await response.Content.ReadAsStringAsync();

            Assert.Contains("Topbar", content);
        }
Example #8
0
        public async Task IndexUrl_ReturnsCustomIndexHtml_IfConfigured()
        {
            var client = new TestSite(typeof(CustomUIIndex.Startup)).BuildClient();

            var response = await client.GetAsync("/swagger/index.html");

            var content = await response.Content.ReadAsStringAsync();

            Assert.Contains("Example.com", content);
        }
        public async Task SwaggerUIIndex_PageTitleChanged_IfConfigured()
        {
            var client = new TestSite(typeof(CustomUIConfig.Startup)).BuildClient();

            var response = await client.GetAsync("/swagger/");

            var content = await response.Content.ReadAsStringAsync();

            Assert.Contains("<title>Custom API - Swagger UI</title>", content);
        }
        public async Task SwaggerUIIndex_ServesAnEmbeddedVersionOfTheSwaggerUI()
        {
            var client = new TestSite(typeof(Basic.Startup)).BuildClient();

            var response = await client.GetAsync("/"); // Basic is configured to serve UI at root

            var content = await response.Content.ReadAsStringAsync();

            Assert.Contains("SwaggerUIBundle", content);
        }
Example #11
0
        public async Task IndexUrl_ReturnsCustomPageTitleAndStylesheets_IfConfigured()
        {
            var client = new TestSite(typeof(CustomUIConfig.Startup)).BuildClient();

            var response = await client.GetAsync("/swagger/index.html");

            var content = await response.Content.ReadAsStringAsync();

            Assert.Contains("<title>CustomUIConfig</title>", content);
            Assert.Contains("<link href='/ext/custom-stylesheet.css' rel='stylesheet' media='screen' type='text/css' />", content);
        }
        public async Task SwaggerUIIndex_IncludesCustomStylesheetsAndScripts_IfConfigured()
        {
            var client = new TestSite(typeof(CustomUIConfig.Startup)).BuildClient();

            var response = await client.GetAsync("/swagger/");

            var content = await response.Content.ReadAsStringAsync();

            Assert.Contains("/ext/custom-script.js", content);
            Assert.Contains("<link href='/ext/custom-stylesheet.css' rel='stylesheet' media='screen' type='text/css' />", content);
        }
Example #13
0
        public async Task ReDocMiddleware_CanBeConfiguredMultipleTimes(string redocUrl, string swaggerPath)
        {
            var client = new TestSite(typeof(MultipleVersions.Startup)).BuildClient();

            var response = await client.GetAsync(redocUrl);

            var content = await response.Content.ReadAsStringAsync();

            Assert.Equal(HttpStatusCode.OK, response.StatusCode);
            Assert.Contains(swaggerPath, content);
        }
Example #14
0
        public void DocumentProvider_ExposesAllDocumentNames(Type startupType, string[] expectedNames)
        {
            var testSite         = new TestSite(startupType);
            var server           = testSite.BuildServer();
            var services         = server.Host.Services;
            var documentProvider = (IDocumentProvider)services.GetService(typeof(IDocumentProvider));

            var documentNames = documentProvider.GetDocumentNames();

            Assert.Equal(expectedNames, documentNames);
        }
Example #15
0
        public async Task VersionUrls_ProperlyHandlesDifferentVersions(string redocUrl, string swaggerPath)
        {
            var client = new TestSite(typeof(MultipleVersions.Startup)).BuildClient();

            var response = await client.GetAsync(redocUrl);

            var content = await response.Content.ReadAsStringAsync();

            Assert.Equal(HttpStatusCode.OK, response.StatusCode);
            Assert.Contains(swaggerPath, content);
        }
        public async Task RoutePrefix_RedirectsToPathRelativeIndexUrl(
            Type startupType,
            string requestPath,
            string expectedRedirectPath)
        {
            var client = new TestSite(startupType).BuildClient();

            var response = await client.GetAsync(requestPath);

            Assert.Equal(HttpStatusCode.MovedPermanently, response.StatusCode);
            Assert.Equal(expectedRedirectPath, response.Headers.Location.ToString());
        }
        public async Task SwaggerEndpoint_ReturnsValidSwaggerJson(
            Type startupType,
            string swaggerRequestUri)
        {
            var testSite = new TestSite(startupType);
            var client   = testSite.BuildClient();

            var swaggerResponse = await client.GetAsync(swaggerRequestUri);

            swaggerResponse.EnsureSuccessStatusCode();
            await AssertResponseDoesNotContainByteOrderMark(swaggerResponse);
            await AssertValidSwaggerAsync(swaggerResponse);
        }
Example #18
0
        public async Task IndexUrl_ReturnsEmbeddedVersionOfTheReDocUI()
        {
            var client = new TestSite(typeof(ReDocApp.Startup)).BuildClient();

            var indexResponse = await client.GetAsync("/api-docs/index.html");

            var jsResponse = await client.GetAsync("/api-docs/redoc.standalone.js");

            var indexContent = await indexResponse.Content.ReadAsStringAsync();

            Assert.Contains("Redoc.init", indexContent);
            Assert.Equal(HttpStatusCode.OK, jsResponse.StatusCode);
        }
Example #19
0
        public async Task SwaggerEndpoint_DoesNotReturnByteOrderMark()
        {
            var testSite = new TestSite(typeof(Basic.Startup));
            var client   = testSite.BuildClient();

            var swaggerResponse = await client.GetAsync("/swagger/v1/swagger.json");

            swaggerResponse.EnsureSuccessStatusCode();
            var contentBytes = await swaggerResponse.Content.ReadAsByteArrayAsync();

            var bomBytes = Encoding.UTF8.GetPreamble();

            Assert.NotEqual(bomBytes, contentBytes.Take(bomBytes.Length));
        }
Example #20
0
        public async Task DocumentProvider_ThrowsUnknownDocument_IfUnknownDocumentName()
        {
            var testSite = new TestSite(typeof(Basic.Startup));
            var server   = testSite.BuildServer();
            var services = server.Host.Services;

            var documentProvider = (IDocumentProvider)services.GetService(typeof(IDocumentProvider));

            using (var writer = new StringWriter())
            {
                await Assert.ThrowsAsync <UnknownSwaggerDocument>(
                    () => documentProvider.GenerateAsync("NotADocument", writer));
            }
        }
Example #21
0
        public async Task SwaggerUIMiddleware_CanBeConfiguredMultipleTimes(string swaggerUiUrl, string[] versions)
        {
            var client = new TestSite(typeof(MultipleVersions.Startup)).BuildClient();

            var response = await client.GetAsync(swaggerUiUrl);

            var content = await response.Content.ReadAsStringAsync();

            Assert.Equal(HttpStatusCode.OK, response.StatusCode);
            foreach (var version in versions)
            {
                Assert.Contains(version, content);
            }
        }
Example #22
0
        public async Task SwaggerEndpoint_ReturnsValidSwaggerJson(
            Type startupType,
            string swaggerRequestUri)
        {
            var testSite = new TestSite(startupType);
            var client   = testSite.BuildClient();

            var swaggerResponse = await client.GetAsync(swaggerRequestUri);

            swaggerResponse.EnsureSuccessStatusCode();
            var contentStream = await swaggerResponse.Content.ReadAsStreamAsync();

            new OpenApiStreamReader().Read(contentStream, out OpenApiDiagnostic diagnostic);
            Assert.Empty(diagnostic.Errors);
        }
Example #23
0
        public async Task SwaggerEndpoint_ReturnsValidSwaggerOpenApiExamplesSchema()
        {
            var testSite = new TestSite(typeof(Basic.Startup));
            var client   = testSite.BuildClient();

            var swaggerResponse = await client.GetAsync("/swagger/v1/swagger.json");

            var contentStream = await swaggerResponse.Content.ReadAsStreamAsync();

            var openApiDocument = new OpenApiStreamReader().Read(contentStream, out OpenApiDiagnostic diagnostic);

            openApiDocument.Components.Schemas["Product"]
            .Example.Should()
            .BeEquivalentTo(Basic.Swagger.ExamplesSchemaFilter.Schemas["Product"]);
        }
Example #24
0
        public async Task SwaggerMiddleware_CanBeConfiguredMultipleTimes(
            string swaggerUrl,
            string expectedVersionProperty,
            string expectedVersionValue)
        {
            var client = new TestSite(typeof(Basic.Startup)).BuildClient();

            var response = await client.GetAsync(swaggerUrl);

            response.EnsureSuccessStatusCode();
            var contentStream = await response.Content.ReadAsStreamAsync();

            var json = await JsonSerializer.DeserializeAsync <JsonElement>(contentStream);

            Assert.Equal(expectedVersionValue, json.GetProperty(expectedVersionProperty).GetString());
        }
Example #25
0
        public async Task IndexUrl_ReturnsEmbeddedVersionOfTheSwaggerUI()
        {
            var client = new TestSite(typeof(Basic.Startup)).BuildClient();

            var indexResponse = await client.GetAsync("/index.html"); // Basic is configured to serve UI at root

            var jsResponse = await client.GetAsync("/swagger-ui.js");

            var cssResponse = await client.GetAsync("/swagger-ui.css");

            var indexContent = await indexResponse.Content.ReadAsStringAsync();

            Assert.Contains("SwaggerUIBundle", indexContent);
            Assert.Equal(HttpStatusCode.OK, jsResponse.StatusCode);
            Assert.Equal(HttpStatusCode.OK, cssResponse.StatusCode);
        }
        public async Task SwaggerEndpoint_InfersServerMetadataFromReverseProxyHeaders_IfPresent(
            string xForwardedFor,
            string xForwardedHost,
            string xForwardedProto,
            string xForwardedPort,
            string xForwardedPrefix,
            string expectedServerUrl)
        {
            var testSite = new TestSite(typeof(Basic.Startup));
            var client   = testSite.BuildClient();

            if (xForwardedFor != null)
            {
                client.DefaultRequestHeaders.Add("X-Forwarded-For", xForwardedFor);
            }

            if (xForwardedHost != null)
            {
                client.DefaultRequestHeaders.Add("X-Forwarded-Host", xForwardedHost);
            }

            if (xForwardedProto != null)
            {
                client.DefaultRequestHeaders.Add("X-Forwarded-Proto", xForwardedProto);
            }

            if (xForwardedPort != null)
            {
                client.DefaultRequestHeaders.Add("X-Forwarded-Port", xForwardedPort);
            }

            if (xForwardedPrefix != null)
            {
                client.DefaultRequestHeaders.Add("X-Forwarded-Prefix", xForwardedPrefix);
            }

            var swaggerResponse = await client.GetAsync("/swagger/v1/swagger.json");

            var contentStream = await swaggerResponse.Content.ReadAsStreamAsync();

            var openApiDocument = new OpenApiStreamReader().Read(contentStream, out _);

            Assert.NotNull(openApiDocument.Servers);
            Assert.NotEmpty(openApiDocument.Servers);
            Assert.Equal(expectedServerUrl, openApiDocument.Servers[0].Url);
        }
Example #27
0
        public async Task SwaggerEndpoint_InfersServerMetadata_FromRequestHeaders(
            string clientBaseAddress,
            string expectedServerUrl)
        {
            var client = new TestSite(typeof(Basic.Startup)).BuildClient();

            client.BaseAddress = new Uri(clientBaseAddress);

            var swaggerResponse = await client.GetAsync($"swagger/v1/swagger.json");

            swaggerResponse.EnsureSuccessStatusCode();
            var contentStream = await swaggerResponse.Content.ReadAsStreamAsync();

            var openApiDoc = new OpenApiStreamReader().Read(contentStream, out _);

            Assert.NotNull(openApiDoc.Servers);
            Assert.Equal(1, openApiDoc.Servers.Count);
            Assert.Equal(expectedServerUrl, openApiDoc.Servers[0].Url);
        }
        public async Task SwaggerEndpoint_ReturnsValidSwaggerJson(
            Type startupType,
            string swaggerRequestUri)
        {
            var testSite = new TestSite(startupType);
            var client   = testSite.BuildClient();

            var swaggerResponse = await client.GetAsync(swaggerRequestUri);

            swaggerResponse.EnsureSuccessStatusCode();

            // NOTE: the online swagger validator INCORRECTLY returns an error for the Swagger generated
            // by the "Basic" sample Website. As a temporary workaround, bypass the valid swagger assertion
            if (startupType == typeof(Basic.Startup))
            {
                return;
            }

            await AssertValidSwaggerAsync(swaggerResponse);
        }
Example #29
0
        public async Task DocumentProvider_ExposesGeneratedSwagger(Type startupType, string documentName)
        {
            var testSite = new TestSite(startupType);
            var server   = testSite.BuildServer();
            var services = server.Host.Services;

            var documentProvider = (IDocumentProvider)services.GetService(typeof(IDocumentProvider));

            using (var stream = new MemoryStream())
            {
                using (var writer = new StreamWriter(stream, Encoding.UTF8, bufferSize: 2048, leaveOpen: true))
                {
                    await documentProvider.GenerateAsync(documentName, writer);

                    await writer.FlushAsync();
                }

                stream.Position = 0L;
                new OpenApiStreamReader().Read(stream, out var diagnostic);
                Assert.NotNull(diagnostic);
                Assert.Empty(diagnostic.Errors);
            }
        }
        public async Task IndexUrl_ReturnsEmbeddedVersionOfTheSwaggerUI(
            Type startupType,
            string indexPath,
            string jsPath,
            string cssPath)
        {
            var client = new TestSite(startupType).BuildClient();

            var indexResponse = await client.GetAsync(indexPath);

            Assert.Equal(HttpStatusCode.OK, indexResponse.StatusCode);
            var indexContent = await indexResponse.Content.ReadAsStringAsync();

            Assert.Contains("SwaggerUIBundle", indexContent);

            var jsResponse = await client.GetAsync(jsPath);

            Assert.Equal(HttpStatusCode.OK, jsResponse.StatusCode);

            var cssResponse = await client.GetAsync(cssPath);

            Assert.Equal(HttpStatusCode.OK, cssResponse.StatusCode);
        }