< Summary

Information
Class: Services.ApiServices.InterpartsPriceApi.InterpartsPriceDiagnosticsStore
Assembly: Services
File(s): /home/runner/work/Studio2Prod/Studio2Prod/AppRepository/ApiServices/InterpartsPriceApi/InterpartsPriceDiagnosticsStore.cs
Line coverage
10%
Covered lines: 2
Uncovered lines: 17
Coverable lines: 19
Total lines: 54
Line coverage: 10.5%
Branch coverage
0%
Covered branches: 0
Total branches: 20
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.cctor()100%210%
.ctor(...)100%11100%
Add(...)0%2040%
Get(...)0%7280%
RemoveExpired()0%2040%
Trim(...)0%2040%

File(s)

/home/runner/work/Studio2Prod/Studio2Prod/AppRepository/ApiServices/InterpartsPriceApi/InterpartsPriceDiagnosticsStore.cs

#LineLine coverage
 1using System.Collections.Concurrent;
 2using Microsoft.AspNetCore.Http;
 3
 4namespace Services.ApiServices.InterpartsPriceApi;
 5
 6public sealed record InterpartsPriceDiagnosticsEntry(
 7    Guid Id,
 8    string? UserName,
 9    DateTimeOffset CreatedAt,
 10    string RequestUrl,
 11    int? StatusCode,
 12    string ErrorMessage,
 13    string ResponseBody);
 14
 15/// <summary>Короткоживущие безопасные детали ответов Interparts Price для открытия из UI.</summary>
 16public sealed class InterpartsPriceDiagnosticsStore
 17{
 018    private static readonly TimeSpan Lifetime = TimeSpan.FromMinutes(15);
 519    private readonly ConcurrentDictionary<Guid, InterpartsPriceDiagnosticsEntry> _entries = new();
 20    private readonly IHttpContextAccessor _httpContextAccessor;
 21
 1022    public InterpartsPriceDiagnosticsStore(IHttpContextAccessor httpContextAccessor) => _httpContextAccessor = httpConte
 23
 24    public Guid Add(string requestUrl, int? statusCode, string errorMessage, string? responseBody)
 25    {
 026        RemoveExpired();
 027        var id = Guid.NewGuid();
 028        var userName = _httpContextAccessor.HttpContext?.User.Identity?.Name;
 029        _entries[id] = new InterpartsPriceDiagnosticsEntry(id, userName, DateTimeOffset.Now, requestUrl,
 030            statusCode, errorMessage, Trim(responseBody));
 031        return id;
 32    }
 33
 34    public InterpartsPriceDiagnosticsEntry? Get(Guid id)
 35    {
 036        RemoveExpired();
 037        if (!_entries.TryGetValue(id, out var entry)) return null;
 038        var userName = _httpContextAccessor.HttpContext?.User.Identity?.Name;
 039        return string.Equals(entry.UserName, userName, StringComparison.OrdinalIgnoreCase) ? entry : null;
 40    }
 41
 42    private void RemoveExpired()
 43    {
 044        var threshold = DateTimeOffset.Now - Lifetime;
 045        foreach (var entry in _entries.Where(x => x.Value.CreatedAt < threshold))
 046            _entries.TryRemove(entry.Key, out _);
 047    }
 48
 49    private static string Trim(string? value)
 50    {
 051        if (string.IsNullOrWhiteSpace(value)) return "—";
 052        return value.Length <= 12000 ? value : value[..12000] + "\n… ответ сокращён";
 53    }
 54}