< Summary

Information
Class: Services.ApiServices.AvdApi.AvdSoapClient
Assembly: Services
File(s): /home/runner/work/Studio2Prod/Studio2Prod/AppRepository/ApiServices/AvdApi/AvdSoapClient.cs
Line coverage
97%
Covered lines: 44
Uncovered lines: 1
Coverable lines: 45
Total lines: 73
Line coverage: 97.7%
Branch coverage
83%
Covered branches: 25
Total branches: 30
Branch coverage: 83.3%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.cctor()100%11100%
.ctor(...)100%11100%
SendAsync()79.16%242496.96%
Value(...)100%22100%
DecimalValue(...)100%22100%
IntValue(...)100%22100%

File(s)

/home/runner/work/Studio2Prod/Studio2Prod/AppRepository/ApiServices/AvdApi/AvdSoapClient.cs

#LineLine coverage
 1using System.Globalization;
 2using System.Xml.Linq;
 3using Services.ApiServices.ApiSupplierRequestLog;
 4
 5namespace Services.ApiServices.AvdApi;
 6
 7public sealed class AvdSoapClient
 8{
 19    private static readonly XNamespace SoapNs = "http://schemas.xmlsoap.org/soap/envelope/";
 110    private static readonly XNamespace ServiceNs = "http://tempuri.org/";
 111    private static readonly XNamespace SerializationArraysNs = "http://schemas.microsoft.com/2003/10/Serialization/Array
 12    private readonly IHttpClientFactory _factory;
 13    private readonly AvdConfig _config;
 14    private readonly ApiSupplierRequestLogStore _logs;
 15
 4616    public AvdSoapClient(IHttpClientFactory factory, AvdConfig config, ApiSupplierRequestLogStore logs)
 17    {
 4618        _factory = factory;
 4619        _config = config;
 4620        _logs = logs;
 4621    }
 22
 23    public async Task<XElement> SendAsync(
 24        string operation,
 25        IReadOnlyDictionary<string, string?>? parameters = null,
 26        CancellationToken ct = default,
 27        IReadOnlyDictionary<string, IReadOnlyCollection<long>>? intArrayParameters = null)
 28    {
 4329        if (string.IsNullOrWhiteSpace(_config.Login) || string.IsNullOrWhiteSpace(_config.Password))
 030            throw new AvdApiException("Не настроены Avd:Login и/или Avd:Password.");
 31
 4332        var operationElement = new XElement(ServiceNs + operation,
 4333            new XElement(ServiceNs + "login", _config.Login),
 4334            new XElement(ServiceNs + "password", _config.Password));
 40435        foreach (var parameter in parameters ?? new Dictionary<string, string?>())
 15936            operationElement.Add(new XElement(ServiceNs + parameter.Key, parameter.Value ?? string.Empty));
 9037        foreach (var parameter in intArrayParameters ?? new Dictionary<string, IReadOnlyCollection<long>>())
 238            operationElement.Add(new XElement(ServiceNs + parameter.Key,
 539                parameter.Value.Select(value => new XElement(SerializationArraysNs + "int", value))));
 4340        var document = new XDocument(new XDeclaration("1.0", "utf-8", null),
 4341            new XElement(SoapNs + "Envelope", new XElement(SoapNs + "Body", operationElement)));
 4342        var body = document.ToString(SaveOptions.DisableFormatting);
 4343        var timer = System.Diagnostics.Stopwatch.StartNew();
 44        try
 45        {
 4346            using var request = new HttpRequestMessage(HttpMethod.Post, _config.BaseUrl)
 4347            {
 4348                Content = new StringContent(body, System.Text.Encoding.UTF8, "text/xml")
 4349            };
 4350            request.Headers.TryAddWithoutValidation("SOAPAction", $"http://tempuri.org/IAvdUserService/{operation}");
 4351            using var response = await _factory.CreateClient("AvdApi").SendAsync(request, ct);
 4152            var responseText = await response.Content.ReadAsStringAsync(ct);
 4153            _logs.Add("Avd", "POST", operation, (int)response.StatusCode, timer, body, responseText);
 4154            if (!response.IsSuccessStatusCode)
 455                throw new AvdApiException($"АВД вернул HTTP {(int)response.StatusCode}.", (int)response.StatusCode);
 3756            var xml = XDocument.Parse(responseText);
 3757            var fault = xml.Descendants(SoapNs + "Fault").FirstOrDefault();
 3758            if (fault != null)
 359                throw new AvdApiException($"АВД вернул SOAP Fault: {fault.Element("faultstring")?.Value ?? "без описания
 3460            return xml.Root ?? throw new AvdApiException("АВД вернул пустой SOAP-ответ.");
 61        }
 1462        catch (AvdApiException) { throw; }
 263        catch (Exception ex)
 64        {
 265            _logs.Add("Avd", "POST", operation, null, timer, body, ex.Message);
 266            throw new AvdApiException("Не удалось выполнить SOAP-запрос к АВД.", innerException: ex);
 67        }
 3468    }
 69
 451870    public static string? Value(XElement element, string name) => element.Elements().FirstOrDefault(x => x.Name.LocalNam
 15471    public static decimal? DecimalValue(XElement element, string name) => decimal.TryParse(Value(element, name), NumberS
 4972    public static int? IntValue(XElement element, string name) => int.TryParse(Value(element, name), NumberStyles.Intege
 73}