< Summary

Information
Line coverage
0%
Covered lines: 0
Uncovered lines: 69
Coverable lines: 69
Total lines: 102
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 12
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity Line coverage
<Main>$(...)0%120%

File(s)

D:\a\smart-meal-planner\smart-meal-planner\backend\Backend\Program.cs

#LineLine coverage
 1using System.Text;
 2using Backend.Services.Impl;
 3using Microsoft.AspNetCore.Authentication.JwtBearer;
 4using Microsoft.EntityFrameworkCore;
 5using Microsoft.IdentityModel.Tokens;
 6using Backend.Model;
 7using Backend.Services;
 8using Serilog;
 9using Microsoft.AspNetCore.Diagnostics;
 10
 011var builder = WebApplication.CreateBuilder(args);
 12
 13// Configure logging
 14// Use Serilog in production, built-in logging in development
 015if (builder.Environment.IsDevelopment())
 16{
 17    // Development: built-in logging (console + debug)
 018    builder.Logging.ClearProviders();
 019    builder.Logging.AddConsole();
 020    builder.Logging.AddDebug();
 021    builder.Logging.AddJsonConsole(); // optional structured output
 22}
 23else
 24{
 25    // Production: use Serilog
 026    Log.Logger = new LoggerConfiguration()
 027        .Enrich.FromLogContext()
 028        .ReadFrom.Configuration(builder.Configuration) // read settings from appsettings.Production.json
 029        .WriteTo.Console()
 030        .WriteTo.File("logs/log-.txt", rollingInterval: RollingInterval.Day)
 031        .CreateLogger();
 32
 033    builder.Host.UseSerilog();
 34}
 35
 36// Pull the connection string from configuration (works for both dev & prod)
 037var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
 38
 039if (string.IsNullOrEmpty(connectionString))
 040    throw new InvalidOperationException("Connection string 'DefaultConnection' is not configured in appsettings.json");
 41
 042builder.Services.AddDbContext<Backend.PlannerContext>(options =>
 043    options.UseNpgsql(connectionString));
 44
 45
 046builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
 047    .AddJwtBearer(options =>
 048    {
 049        var rawKey = builder.Configuration["Jwt:Key"];
 050        if (string.IsNullOrEmpty(rawKey))
 051            throw new InvalidOperationException("JWT Key is not configured in appsettings.json");
 052
 053        var key = Encoding.UTF8.GetBytes(rawKey);
 054        options.TokenValidationParameters = new TokenValidationParameters
 055        {
 056            ValidateIssuer = true,
 057            ValidateAudience = true,
 058            ValidateLifetime = true,
 059            ValidateIssuerSigningKey = true,
 060            ValidIssuer = builder.Configuration["Jwt:Issuer"] ?? "Backend",
 061            ValidAudience = builder.Configuration["Jwt:Audience"] ?? "SmartMealPlannerUsers",
 062            IssuerSigningKey = new SymmetricSecurityKey(key),
 063            ClockSkew = TimeSpan.Zero // Optional: Set to zero to avoid delay in token expiration
 064        };
 065    });
 66
 067builder.Services.AddAuthorization();
 068builder.Services.AddControllers();
 069builder.Services.AddEndpointsApiExplorer();
 070builder.Services.AddSwaggerGen();
 71
 072builder.Services.AddScoped<ITokenService, TokenService>();
 073builder.Services.AddScoped<ICategoryService, CategoryService>();
 074builder.Services.AddScoped<IUserService, UserSerivce>();
 075builder.Services.AddScoped<IEmailService, BrevoEmailService>();
 76
 077var app = builder.Build();
 78
 079app.UseSwagger();
 080app.UseSwaggerUI();
 081app.UseHttpsRedirection();
 082app.UseAuthentication();
 083app.UseAuthorization();
 084app.UseSerilogRequestLogging();
 85
 086app.UseExceptionHandler(errorApp =>
 087{
 088    errorApp.Run(async context =>
 089    {
 090        var exceptionHandlerPathFeature = context.Features.Get<IExceptionHandlerPathFeature>();
 091        var exception = exceptionHandlerPathFeature?.Error;
 092
 093        var logger = app.Services.GetRequiredService<ILogger<Program>>();
 094        logger.LogError(exception, "An unhandled exception occurred.");
 095
 096        context.Response.StatusCode = 500;
 097        await context.Response.WriteAsJsonAsync(new { error = "An unexpected error occurred." });
 098    });
 099});
 100
 0101app.MapControllers();
 0102app.Run();

Methods/Properties

<Main>$(System.String[])