< Summary

Information
Class: OzonOrdersWeb.Areas.Studio2.AnalysisServices.OzonErrorLink
Assembly: OzonOrdersWeb
File(s): /home/runner/work/Studio2Prod/Studio2Prod/OzonOrdersWeb/Areas/Studio2/AnalysisServices/OzonErrorLinksService.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 1
Coverable lines: 1
Total lines: 56
Line coverage: 0%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
get_ClientName()100%210%

File(s)

/home/runner/work/Studio2Prod/Studio2Prod/OzonOrdersWeb/Areas/Studio2/AnalysisServices/OzonErrorLinksService.cs

#LineLine coverage
 1using Microsoft.Extensions.Caching.Memory;
 2using OzonDomains;
 3using OzonDomains.Models;
 4using Services.DataServices;
 5
 6namespace OzonOrdersWeb.Areas.Studio2.AnalysisServices;
 7
 08public sealed record OzonErrorLink(string ClientName, string ClientId, string Url, bool IsAvailable, string Reason);
 9
 10/// <summary>
 11/// Проверка доступности dashboard ошибок Ozon по каждому клиенту (внешний сервис OzonErrorDashboard:BaseUrl):
 12/// параллельные запросы через IHttpClientFactory, результат кэшируется на 2 минуты (кнопка «Проверить заново» обходит к
 13/// </summary>
 14public sealed class OzonErrorLinksService(OzonClientServices clients, IHttpClientFactory httpClientFactory, IMemoryCache
 15{
 16    private static readonly TimeSpan Ttl = TimeSpan.FromMinutes(2);
 17    private readonly string _baseUrl = (configuration["OzonErrorDashboard:BaseUrl"] ?? string.Empty).TrimEnd('/');
 18
 19    public async Task<IReadOnlyList<OzonErrorLink>> GetAsync(bool refresh, CancellationToken ct)
 20    {
 21        const string key = "pa.ozon-error-links";
 22        if (!refresh && cache.TryGetValue(key, out IReadOnlyList<OzonErrorLink>? cached) && cached != null) return cache
 23
 24        var ozonClients = (await clients.GetOzonClients())
 25            .Where(c => c.ClientType == ClientType.OZON).OrderBy(c => c.Name).ToList();
 26        var result = await Task.WhenAll(ozonClients.Select(c => CheckAsync(c, ct)));
 27        cache.Set(key, (IReadOnlyList<OzonErrorLink>)result, Ttl);
 28        return result;
 29    }
 30
 31    private async Task<OzonErrorLink> CheckAsync(OzonClient client, CancellationToken ct)
 32    {
 33        var raw = string.IsNullOrWhiteSpace(client.DecryptClientId) ? client.ClientId : client.DecryptClientId;
 34        var clientId = (raw ?? string.Empty).Trim();
 35        var name = client.Name ?? string.Empty;
 36        if (string.IsNullOrWhiteSpace(clientId) || string.IsNullOrWhiteSpace(_baseUrl))
 37            return new OzonErrorLink(name, clientId, string.Empty, false, "Не указан ClientId");
 38
 39        var link = $"{_baseUrl}/{Uri.EscapeDataString(clientId)}/dashboard";
 40        try
 41        {
 42            var http = httpClientFactory.CreateClient();
 43            http.Timeout = TimeSpan.FromSeconds(5);
 44            using var response = await http.GetAsync(link, ct);
 45            var body = await response.Content.ReadAsStringAsync(ct);
 46            var notFound = body.Contains("\"detail\":\"Клиент не найден в базе\"", StringComparison.OrdinalIgnoreCase);
 47            var available = response.IsSuccessStatusCode && !notFound;
 48            return new OzonErrorLink(name, clientId, link, available,
 49                available ? string.Empty : notFound ? "Клиент не найден в базе" : $"HTTP {(int)response.StatusCode}");
 50        }
 51        catch (Exception ex) when (ex is not OperationCanceledException || !ct.IsCancellationRequested)
 52        {
 53            return new OzonErrorLink(name, clientId, link, false, ex.Message);
 54        }
 55    }
 56}

Methods/Properties

get_ClientName()