< Summary

Information
Class: ArturRios.Util.WebApi.Configuration.WebApplicationBuilderExtensions
Assembly: ArturRios.Util.WebApi
File(s): /home/ci/agent/workspace/dotnet-webapi-util-docs_main/app/src/Configuration/WebApplicationBuilderExtensions.cs
Line coverage
87%
Covered lines: 43
Uncovered lines: 6
Coverable lines: 49
Total lines: 122
Line coverage: 87.7%
Branch coverage
58%
Covered branches: 7
Total branches: 12
Branch coverage: 58.3%
Method coverage
75%
Covered methods: 3
Fully covered methods: 2
Total methods: 4
Method coverage: 75%
Full method coverage: 50%

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
LoadConfiguration(...)50%4480%
AddWebApiSwagger(...)0%620%
AddWebApiSwaggerWith(...)83.33%66100%
AddJwtSecurity(...)100%11100%

File(s)

/home/ci/agent/workspace/dotnet-webapi-util-docs_main/app/src/Configuration/WebApplicationBuilderExtensions.cs

#LineLine coverage
 1using ArturRios.Configuration.Loaders;
 2using ArturRios.Configuration.Providers;
 3using Microsoft.AspNetCore.Authentication.JwtBearer;
 4using Microsoft.AspNetCore.Builder;
 5using Microsoft.Extensions.Configuration;
 6using Microsoft.Extensions.DependencyInjection;
 7using Microsoft.Extensions.DependencyInjection.Extensions;
 8using Microsoft.Extensions.Logging;
 9using Microsoft.OpenApi;
 10using Swashbuckle.AspNetCore.SwaggerGen;
 11
 12namespace ArturRios.Util.WebApi.Configuration;
 13
 14/// <summary>Builder-side steps of the standard web API setup. <see cref="WebApiStartup"/> runs them in order, and each
 15/// one can be used on its own with a plain <see cref="WebApplicationBuilder"/>.</summary>
 16public static class WebApplicationBuilderExtensions
 17{
 18    /// <param name="builder">The application builder.</param>
 19    extension(WebApplicationBuilder builder)
 20    {
 21        /// <summary>Loads <c>appsettings</c> and/or the environment file according to <paramref name="parameters"/>, an
 22        /// registers <paramref name="parameters"/>, the <see cref="ConfigurationLoader"/>, <see cref="SettingsProvider"
 23        /// (always, since <c>AuthenticationMiddleware</c> depends on it) and <see cref="EnvironmentProvider"/> (when th
 24        /// environment file is loaded) as services.</summary>
 25        /// <param name="parameters">The startup parameters deciding which sources are loaded.</param>
 26        /// <returns>The same <paramref name="builder"/> instance, for chaining.</returns>
 27        public WebApplicationBuilder LoadConfiguration(WebApiParameters parameters)
 28        {
 2729            ArgumentNullException.ThrowIfNull(parameters);
 30
 2731            var environmentName = builder.Environment.EnvironmentName;
 32
 2733            builder.Services.TryAddSingleton(parameters);
 2734            builder.Services.TryAddSingleton(sp => new ConfigurationLoader(builder.Configuration, environmentName, null,
 2735                sp.GetRequiredService<ILogger<ConfigurationLoader>>()));
 2736            builder.Services.TryAddSingleton<SettingsProvider>();
 37
 5438            using var loggerFactory = LoggerFactory.Create(logging => logging.AddConsole());
 39
 2740            var configurationLoader = new ConfigurationLoader(builder.Configuration, environmentName, null,
 2741                loggerFactory.CreateLogger<ConfigurationLoader>());
 42
 2743            if (parameters.UseAppSettings)
 44            {
 045                configurationLoader.LoadAppSettings();
 46            }
 47
 2748            if (parameters.UseEnvFile)
 49            {
 050                configurationLoader.LoadEnvironment();
 51
 052                builder.Services.TryAddSingleton<EnvironmentProvider>();
 53            }
 54
 2755            return builder;
 56        }
 57
 58        /// <summary>Registers the Swagger generator when Swagger is allowed in the current environment (see
 59        /// <see cref="WebApiParameters.IsSwaggerAllowed"/>), and marks it enabled under
 60        /// <see cref="AppSettingsKeys.SwaggerEnabled"/> so <c>AuthenticationMiddleware</c> lets <c>/swagger</c> through
 61        /// Pair it with <see cref="ApplicationBuilderExtensions.UseWebApiSwagger"/>, which serves whatever was register
 62        /// <param name="parameters">The startup parameters gating Swagger by environment.</param>
 63        /// <param name="configure">Optional callback to configure the allowed environments, JWT security and generator.
 64        /// <returns>The same <paramref name="builder"/> instance, for chaining.</returns>
 65        public WebApplicationBuilder AddWebApiSwagger(WebApiParameters parameters, Action<WebApiSwaggerOptions>? configu
 66        {
 067            var options = new WebApiSwaggerOptions();
 068            configure?.Invoke(options);
 69
 070            return builder.AddWebApiSwaggerWith(parameters, options);
 71        }
 72
 73        internal WebApplicationBuilder AddWebApiSwaggerWith(WebApiParameters parameters, WebApiSwaggerOptions options)
 74        {
 2775            ArgumentNullException.ThrowIfNull(parameters);
 76
 2777            if (!parameters.IsSwaggerAllowed(builder.Environment.EnvironmentName, options.AllowedEnvironments))
 78            {
 2279                return builder;
 80            }
 81
 582            builder.Configuration.AddInMemoryCollection(
 583                new Dictionary<string, string?> { [AppSettingsKeys.SwaggerEnabled] = "true" });
 84
 585            builder.Services.AddSwaggerGen(generator =>
 586            {
 487                options.ConfigureGenerator?.Invoke(generator);
 588
 489                if (options.JwtAuthentication)
 590                {
 191                    AddJwtSecurity(generator);
 592                }
 993            });
 94
 595            return builder;
 96        }
 97    }
 98
 99    private static void AddJwtSecurity(SwaggerGenOptions options)
 100    {
 1101        var jwtSecurityScheme = new OpenApiSecurityScheme
 1102        {
 1103            BearerFormat = "JWT",
 1104            Name = "JWT Authentication",
 1105            In = ParameterLocation.Header,
 1106            Type = SecuritySchemeType.Http,
 1107            Scheme = JwtBearerDefaults.AuthenticationScheme,
 1108            Description =
 1109                "After getting a token from the Authentication route, put **_ONLY_** your JWT Bearer token on textbox be
 1110        };
 111
 1112        options.AddSecurityDefinition(JwtBearerDefaults.AuthenticationScheme, jwtSecurityScheme);
 113
 114        // The reference must be bound to the document being generated: one without a host document has no target,
 115        // and Microsoft.OpenApi then writes the requirement as an empty object ({}), which tells Swagger UI the
 116        // operations need no credentials, so the token entered under "Authorize" was never sent.
 2117        options.AddSecurityRequirement(document => new OpenApiSecurityRequirement
 2118        {
 2119            { new OpenApiSecuritySchemeReference(JwtBearerDefaults.AuthenticationScheme, document), [] }
 2120        });
 1121    }
 122}