< Summary - Kestrun — Combined Coverage

Information
Class: Kestrun.Models.KestrunContext
Assembly: Kestrun
File(s): /home/runner/work/Kestrun/Kestrun/src/CSharp/Kestrun/Models/KestrunContext.cs
Tag: Kestrun/Kestrun@2d87023b37eb91155071c91dd3d6a2eeb3004705
Line coverage
39%
Covered lines: 30
Uncovered lines: 46
Coverable lines: 76
Total lines: 252
Line coverage: 39.4%
Branch coverage
25%
Covered branches: 5
Total branches: 20
Branch coverage: 25%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100 09/12/2025 - 03:43:11 Line coverage: 100% (9/9) Branch coverage: 62.5% (5/8) Total lines: 54 Tag: Kestrun/Kestrun@d160286e3020330b1eb862d66a37db2e26fc904210/13/2025 - 16:52:37 Line coverage: 100% (30/30) Branch coverage: 62.5% (5/8) Total lines: 108 Tag: Kestrun/Kestrun@10d476bee71c71ad215bb8ab59f219887b5b4a5e10/15/2025 - 21:27:26 Line coverage: 40% (30/75) Branch coverage: 25% (5/20) Total lines: 247 Tag: Kestrun/Kestrun@c33ec02a85e4f8d6061aeaab5a5e8c3a8b66559410/17/2025 - 15:48:30 Line coverage: 39.4% (30/76) Branch coverage: 25% (5/20) Total lines: 252 Tag: Kestrun/Kestrun@b8199aff869a847b75e185d0527ba45e04a43d86 09/12/2025 - 03:43:11 Line coverage: 100% (9/9) Branch coverage: 62.5% (5/8) Total lines: 54 Tag: Kestrun/Kestrun@d160286e3020330b1eb862d66a37db2e26fc904210/13/2025 - 16:52:37 Line coverage: 100% (30/30) Branch coverage: 62.5% (5/8) Total lines: 108 Tag: Kestrun/Kestrun@10d476bee71c71ad215bb8ab59f219887b5b4a5e10/15/2025 - 21:27:26 Line coverage: 40% (30/75) Branch coverage: 25% (5/20) Total lines: 247 Tag: Kestrun/Kestrun@c33ec02a85e4f8d6061aeaab5a5e8c3a8b66559410/17/2025 - 15:48:30 Line coverage: 39.4% (30/76) Branch coverage: 25% (5/20) Total lines: 252 Tag: Kestrun/Kestrun@b8199aff869a847b75e185d0527ba45e04a43d86

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
.ctor(...)100%11100%
get_Host()100%11100%
get_Request()100%11100%
get_Response()100%11100%
get_HttpContext()100%11100%
get_Session()100%22100%
get_HasSession()100%11100%
TryGetSession(...)100%11100%
get_Ct()100%11100%
get_Items()100%11100%
get_User()100%11100%
get_Connection()100%210%
ToString()50%66100%
BroadcastLogAsync()0%2040%
BroadcastLog(...)100%210%
BroadcastEventAsync()0%2040%
BroadcastEvent(...)100%210%
BroadcastToGroupAsync()0%2040%
BroadcastToGroup(...)100%210%

File(s)

/home/runner/work/Kestrun/Kestrun/src/CSharp/Kestrun/Models/KestrunContext.cs

#LineLine coverage
 1
 2
 3using System.Security.Claims;
 4using Kestrun.SignalR;
 5using Microsoft.AspNetCore.Http.Features;
 6
 7namespace Kestrun.Models;
 8
 9/// <summary>
 10/// Represents the context for a Kestrun request, including the request, response, HTTP context, and host.
 11/// </summary>
 12public sealed record KestrunContext
 13{
 14    /// <summary>
 15    /// Initializes a new instance of the <see cref="KestrunContext"/> class.
 16    /// This constructor is used when creating a new KestrunContext from an existing HTTP context.
 17    /// It initializes the KestrunRequest and KestrunResponse based on the provided HttpContext
 18    /// </summary>
 19    /// <param name="host">The Kestrun host.</param>
 20    /// <param name="request">The Kestrun request.</param>
 21    /// <param name="response">The Kestrun response.</param>
 22    /// <param name="httpContext">The associated HTTP context.</param>
 4823    public KestrunContext(Hosting.KestrunHost host, KestrunRequest request, KestrunResponse response, HttpContext httpCo
 24    {
 4825        ArgumentNullException.ThrowIfNull(host);
 4826        ArgumentNullException.ThrowIfNull(request);
 4827        ArgumentNullException.ThrowIfNull(response);
 4828        ArgumentNullException.ThrowIfNull(httpContext);
 29
 4830        Host = host;
 4831        Request = request;
 4832        Response = response;
 4833        HttpContext = httpContext;
 4834    }
 35
 36    /// <summary>
 37    /// Initializes a new instance of the <see cref="KestrunContext"/> class.
 38    /// This constructor is used when creating a new KestrunContext from an existing HTTP context.
 39    /// It initializes the KestrunRequest and KestrunResponse based on the provided HttpContext
 40    /// </summary>
 41    /// <param name="host">The Kestrun host.</param>
 42    /// <param name="httpContext">The associated HTTP context.</param>
 143    public KestrunContext(Hosting.KestrunHost host, HttpContext httpContext)
 44    {
 145        ArgumentNullException.ThrowIfNull(host);
 146        ArgumentNullException.ThrowIfNull(httpContext);
 47
 148        Host = host;
 149        HttpContext = httpContext;
 50
 151        Request = KestrunRequest.NewRequestSync(HttpContext);
 152        Response = new KestrunResponse(Request);
 153    }
 54
 55    /// <summary>
 56    /// The Kestrun host associated with this context.
 57    /// </summary>
 5158    public Hosting.KestrunHost Host { get; init; }
 59    /// <summary>
 60    /// The Kestrun request associated with this context.
 61    /// </summary>
 7762    public KestrunRequest Request { get; init; }
 63    /// <summary>
 64    /// The Kestrun response associated with this context.
 65    /// </summary>
 8166    public KestrunResponse Response { get; init; }
 67    /// <summary>
 68    /// The ASP.NET Core HTTP context associated with this Kestrun context.
 69    /// </summary>
 7870    public HttpContext HttpContext { get; init; }
 71    /// <summary>
 72    /// Returns the ASP.NET Core session if the Session middleware is active; otherwise null.
 73    /// </summary>
 1474    public ISession? Session => HttpContext.Features.Get<ISessionFeature>()?.Session;
 75
 76    /// <summary>
 77    /// True if Session middleware is active for this request.
 78    /// </summary>
 479    public bool HasSession => Session is not null;
 80
 81    /// <summary>
 82    /// Try pattern to get session without exceptions.
 83    /// </summary>
 84    public bool TryGetSession(out ISession? session)
 85    {
 286        session = Session;
 287        return session is not null;
 88    }
 89
 90    /// <summary>
 91    /// Gets the cancellation token that is triggered when the HTTP request is aborted.
 92    /// </summary>
 193    public CancellationToken Ct => HttpContext.RequestAborted;
 94    /// <summary>
 95    /// Gets the collection of key/value pairs associated with the current HTTP context.
 96    /// </summary>
 397    public IDictionary<object, object?> Items => HttpContext.Items;
 98
 99    /// <summary>
 100    /// Gets the user associated with the current HTTP context.
 101    /// </summary>
 2102    public ClaimsPrincipal User => HttpContext.User;
 103
 104    /// <summary>
 105    /// Gets the connection information for the current HTTP context.
 106    /// </summary>
 0107    public ConnectionInfo Connection => HttpContext.Connection;
 108
 109    /// <summary>
 110    /// Returns a string representation of the KestrunContext, including path, user, and session status.
 111    /// </summary>
 112    public override string ToString()
 2113        => $"KestrunContext{{ Host={Host}, Path={HttpContext.Request.Path}, User={User?.Identity?.Name ?? "<anon>"}, Has
 114
 115
 116    /// <summary>
 117    /// Asynchronously broadcasts a log message to all connected SignalR clients using the IRealtimeBroadcaster service.
 118    /// </summary>
 119    /// <param name="level">The log level (e.g., Information, Warning, Error, Debug, Verbose).</param>
 120    /// <param name="message">The log message to broadcast.</param>
 121    /// <param name="cancellationToken">Optional: Cancellation token.</param>
 122    /// <returns>True if the log was broadcast successfully; otherwise, false.</returns>
 123    public async Task<bool> BroadcastLogAsync(string level, string message, CancellationToken cancellationToken = defaul
 124    {
 0125        var svcProvider = HttpContext.RequestServices;
 126
 0127        if (svcProvider == null)
 128        {
 0129            Host.Logger.Warning("No service provider available to resolve IRealtimeBroadcaster.");
 0130            return false;
 131        }
 0132        if (svcProvider.GetService(typeof(IRealtimeBroadcaster)) is not IRealtimeBroadcaster broadcaster)
 133        {
 0134            Host.Logger.Warning("IRealtimeBroadcaster service is not registered. Make sure SignalR is configured with Ke
 0135            return false;
 136        }
 137        try
 138        {
 0139            await broadcaster.BroadcastLogAsync(level, message, cancellationToken);
 0140            Host.Logger.Debug("Broadcasted log message via SignalR: {Level} - {Message}", level, message);
 0141            return true;
 142        }
 0143        catch (Exception ex)
 144        {
 0145            Host.Logger.Error(ex, "Failed to broadcast log message: {Level} - {Message}", level, message);
 0146            return false;
 147        }
 0148    }
 149
 150    /// <summary>
 151    /// Synchronous wrapper for BroadcastLogAsync.
 152    /// </summary>
 153    /// <param name="level">The log level (e.g., Information, Warning, Error, Debug, Verbose).</param>
 154    /// <param name="message">The log message to broadcast.</param>
 155    /// <param name="cancellationToken">Optional: Cancellation token.</param>
 156    /// <returns>True if the log was broadcast successfully; otherwise, false.</returns>
 157    public bool BroadcastLog(string level, string message, CancellationToken cancellationToken = default) =>
 0158        BroadcastLogAsync(level, message, cancellationToken).GetAwaiter().GetResult();
 159
 160
 161    /// <summary>
 162    /// Asynchronously broadcasts a custom event to all connected SignalR clients using the IRealtimeBroadcaster service
 163    /// </summary>
 164    /// <param name="eventName">The event name (e.g., Information, Warning, Error, Debug, Verbose).</param>
 165    /// <param name="data">The event data to broadcast.</param>
 166    /// <param name="cancellationToken">Optional: Cancellation token.</param>
 167    /// <returns>True if the event was broadcast successfully; otherwise, false.</returns>
 168    public async Task<bool> BroadcastEventAsync(string eventName, object? data, CancellationToken cancellationToken = de
 169    {
 0170        var svcProvider = HttpContext.RequestServices;
 171
 0172        if (svcProvider == null)
 173        {
 0174            Host.Logger.Warning("No service provider available to resolve IRealtimeBroadcaster.");
 0175            return false;
 176        }
 0177        if (svcProvider.GetService(typeof(IRealtimeBroadcaster)) is not IRealtimeBroadcaster broadcaster)
 178        {
 0179            Host.Logger.Warning("IRealtimeBroadcaster service is not registered. Make sure SignalR is configured with Ke
 0180            return false;
 181        }
 182        try
 183        {
 0184            await broadcaster.BroadcastEventAsync(eventName, data, cancellationToken);
 0185            Host.Logger.Debug("Broadcasted event via SignalR: {EventName} - {Data}", eventName, data);
 0186            return true;
 187        }
 0188        catch (Exception ex)
 189        {
 0190            Host.Logger.Error(ex, "Failed to broadcast event: {EventName} - {Data}", eventName, data);
 0191            return false;
 192        }
 0193    }
 194
 195    /// <summary>
 196    /// Synchronous wrapper for BroadcastEventAsync.
 197    /// </summary>
 198    /// <param name="eventName">The event name (e.g., Information, Warning, Error, Debug, Verbose).</param>
 199    /// <param name="data">The event data to broadcast.</param>
 200    /// <param name="cancellationToken">Optional: Cancellation token.</param>
 201    /// <returns>True if the event was broadcast successfully; otherwise, false.</returns>
 202    public bool BroadcastEvent(string eventName, object? data, CancellationToken cancellationToken = default) =>
 0203      BroadcastEventAsync(eventName, data, cancellationToken).GetAwaiter().GetResult();
 204
 205
 206    /// <summary>
 207    /// Asynchronously broadcasts a message to a specific group of SignalR clients using the IRealtimeBroadcaster servic
 208    /// </summary>
 209    /// <param name="groupName">The name of the group to broadcast the message to.</param>
 210    /// <param name="method">The name of the method to invoke on the client.</param>
 211    /// <param name="message">The message to broadcast.</param>
 212    /// <param name="cancellationToken">Optional: Cancellation token.</param>
 213    /// <returns></returns>
 214    public async Task<bool> BroadcastToGroupAsync(string groupName, string method, object? message, CancellationToken ca
 215    {
 0216        var svcProvider = HttpContext.RequestServices;
 217
 0218        if (svcProvider == null)
 219        {
 0220            Host.Logger.Warning("No service provider available to resolve IRealtimeBroadcaster.");
 0221            return false;
 222        }
 0223        if (svcProvider.GetService(typeof(IRealtimeBroadcaster)) is not IRealtimeBroadcaster broadcaster)
 224        {
 0225            Host.Logger.Warning("IRealtimeBroadcaster service is not registered. Make sure SignalR is configured with Ke
 0226            return false;
 227        }
 228        try
 229        {
 0230            await broadcaster.BroadcastToGroupAsync(groupName, method, message, cancellationToken);
 0231            Host.Logger.Debug("Broadcasted log message to group via SignalR: {GroupName} - {Method} - {Message}", groupN
 0232            return true;
 233        }
 0234        catch (Exception ex)
 235        {
 0236            Host.Logger.Error(ex, "Failed to broadcast log message: {GroupName} - {Method} - {Message}", groupName, meth
 0237            return false;
 238        }
 0239    }
 240
 241    /// <summary>
 242    /// Synchronous wrapper for BroadcastToGroupAsync.
 243    /// </summary>
 244    /// <param name="groupName">The name of the group to broadcast the message to.</param>
 245    /// <param name="method">The name of the method to invoke on the client.</param>
 246    /// <param name="message">The message to broadcast.</param>
 247    /// <param name="cancellationToken">Optional: Cancellation token.</param>
 248    /// <returns></returns>
 249    public bool BroadcastToGroup(string groupName, string method, object? message, CancellationToken cancellationToken =
 0250      BroadcastToGroupAsync(groupName, method, message, cancellationToken).GetAwaiter().GetResult();
 251}
 252