< Summary

Information
Class: Services.ApiServices.MlAutoApi.MlAutoDataManager
Assembly: Services
File(s): /home/runner/work/Studio2Prod/Studio2Prod/AppRepository/ApiServices/MlAutoApi/MlAutoDataManager.cs
Line coverage
59%
Covered lines: 29
Uncovered lines: 20
Coverable lines: 49
Total lines: 82
Line coverage: 59.1%
Branch coverage
59%
Covered branches: 13
Total branches: 22
Branch coverage: 59%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
PingAsync(...)100%210%
PostAsync(...)100%11100%
GetDeliveryAddressesAsync(...)100%210%
CreateOrderTestAsync(...)100%210%
CreateOrderTestDetailedAsync(...)100%210%
CreateOrderAsync(...)100%210%
GetOrderByNumberAsync(...)100%11100%
GetMyOrdersAsync(...)100%210%
GetOrderSummariesAsync()100%210%
GetOrderItemsAsync()100%11100%
Objects(...)50%9657.14%
Value(...)100%22100%

File(s)

/home/runner/work/Studio2Prod/Studio2Prod/AppRepository/ApiServices/MlAutoApi/MlAutoDataManager.cs

#LineLine coverage
 1using Newtonsoft.Json.Linq;
 2
 3namespace Services.ApiServices.MlAutoApi;
 4
 5/// <summary>Транспорт ML-Auto. Методы заказа вызываются только локальной корзиной после подтверждения пользователя.</su
 6public sealed class MlAutoDataManager
 7{
 8    private readonly MlAutoHttpClient _client;
 649    public MlAutoDataManager(MlAutoHttpClient client) => _client = client;
 010    public Task<JToken> PingAsync(CancellationToken cancellationToken = default) => _client.PingAsync(cancellationToken)
 11    public Task<JToken> PostAsync(string path, IReadOnlyDictionary<string, string?>? parameters, CancellationToken cance
 212        => _client.PostAsync(path, parameters, cancellationToken);
 13
 14    public Task<JToken> GetDeliveryAddressesAsync(CancellationToken cancellationToken = default) =>
 015        _client.PostAsync("/MyDeliveryAddress/", null, cancellationToken);
 16
 17    public Task<JToken> CreateOrderTestAsync(IReadOnlyDictionary<string, string?> parameters, CancellationToken cancella
 018        _client.PostAsync("/CreateOrderTest/", parameters, cancellationToken);
 19
 20    public Task<MlAutoApiResponse> CreateOrderTestDetailedAsync(IReadOnlyDictionary<string, string?> parameters, Cancell
 021        _client.PostDetailedAsync("/CreateOrderTest/", parameters, cancellationToken);
 22
 23    public Task<JToken> CreateOrderAsync(IReadOnlyDictionary<string, string?> parameters, CancellationToken cancellation
 024        _client.PostAsync("/CreateOrder/", parameters, cancellationToken);
 25
 26    public Task<JToken> GetOrderByNumberAsync(string orderNumber, CancellationToken cancellationToken = default) =>
 2327        _client.PostAsync("/GetOrderByNumber/", new Dictionary<string, string?> { ["ORDER-NUMBER"] = orderNumber }, canc
 28
 29    public Task<JToken> GetMyOrdersAsync(CancellationToken cancellationToken = default) =>
 030        _client.PostAsync("/GetMyOrders/", null, cancellationToken);
 31
 32    /// <summary>Список заказов личного кабинета: read-only, состав заказа приходит только из GetOrderByNumber.</summary
 33    public async Task<IReadOnlyList<MlAutoOrderSummary>> GetOrderSummariesAsync(CancellationToken cancellationToken = de
 34    {
 035        var response = await GetMyOrdersAsync(cancellationToken);
 036        return Objects(response, "ORDERS")
 037            .Select(x => new MlAutoOrderSummary(
 038                Value(x, "ORDER-NUMBER", "ORDERNUMBER", "NUMBER") ?? string.Empty,
 039                MlAutoValueParser.ParseDate(Value(x, "DATE", "ORDER-DATE"))))
 040            .Where(x => !string.IsNullOrWhiteSpace(x.Number))
 041            .DistinctBy(x => x.Number)
 042            .OrderByDescending(x => x.CreatedAt ?? DateTime.MinValue)
 043            .ThenByDescending(x => x.Number, StringComparer.Ordinal)
 044            .ToArray();
 045    }
 46
 47    /// <summary>Позиции конкретного заказа: read-only запрос, состав заказа не меняет.</summary>
 48    public async Task<IReadOnlyList<MlAutoOrderItemInfo>> GetOrderItemsAsync(string orderNumber, CancellationToken cance
 49    {
 2350        var response = await GetOrderByNumberAsync(orderNumber, cancellationToken);
 1951        return Objects(response, "ITEMS")
 2052            .Select(x => new MlAutoOrderItemInfo(
 2053                Value(x, "PIN") ?? string.Empty,
 2054                Value(x, "BRAND") ?? string.Empty,
 2055                MlAutoValueParser.ParseDecimal(Value(x, "QUANTITY")) ?? 0m,
 2056                Value(x, "STATUS") ?? string.Empty,
 2057                MlAutoValueParser.ParseDecimal(Value(x, "PRICE")),
 2058                MlAutoValueParser.ParseDecimal(Value(x, "SUMM")),
 2059                MlAutoValueParser.ParseFlag(Value(x, "BEZNAL")),
 2060                MlAutoValueParser.ParseFlag(Value(x, "CONFIRMED")),
 2061                MlAutoValueParser.ParseFlag(Value(x, "HAS-SHIPPED")),
 2062                MlAutoValueParser.ParseFlag(Value(x, "REJECTED")),
 2063                MlAutoValueParser.ParseDate(Value(x, "ESTIMATED-DELIVERY-DATE")),
 2064                Value(x, "ITEM-COMMENT") ?? string.Empty,
 2065                Value(x, "ORDER-COMMENT") ?? string.Empty))
 2066            .Where(x => !string.IsNullOrWhiteSpace(x.Pin))
 1967            .ToArray();
 1968    }
 69
 70    /// <summary>RESPONSE приходит либо массивом, либо объектом-обёрткой с массивом внутри.</summary>
 1971    private static IEnumerable<JObject> Objects(JToken token, string arrayName) => token switch
 1972    {
 073        JArray array => array.OfType<JObject>(),
 3874        JObject obj when obj.GetValue(arrayName, StringComparison.OrdinalIgnoreCase) is JArray nested => nested.OfType<J
 075        JObject obj => [obj],
 076        _ => []
 1977    };
 78
 26079    private static string? Value(JObject source, params string[] names) => names
 26080        .Select(name => source.GetValue(name, StringComparison.OrdinalIgnoreCase)?.ToString())
 52081        .FirstOrDefault(value => !string.IsNullOrWhiteSpace(value));
 82}