< Summary

Information
Class: Services.OzonHandoverServices.OzonHandoverPhotoStorage
Assembly: Services
File(s): /home/runner/work/Studio2Prod/Studio2Prod/AppRepository/OzonHandoverServices/OzonHandoverPhotoStorage.cs
Line coverage
100%
Covered lines: 29
Uncovered lines: 0
Coverable lines: 29
Total lines: 55
Line coverage: 100%
Branch coverage
100%
Covered branches: 22
Total branches: 22
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
DownloadAndStoreAsync()100%2222100%
OpenReadAsync()100%11100%
Hash(...)100%11100%

File(s)

/home/runner/work/Studio2Prod/Studio2Prod/AppRepository/OzonHandoverServices/OzonHandoverPhotoStorage.cs

#LineLine coverage
 1using System.Security.Cryptography;
 2using Services.FileStorageServices;
 3
 4namespace Services.OzonHandoverServices;
 5
 6/// <summary>Скачивает краткоживущие фото realFBS и кладёт их в общее файловое хранилище.</summary>
 7public sealed class OzonHandoverPhotoStorage : IOzonHandoverPhotoStorage
 8{
 9    public const string HttpClientName = "OzonHandoverPhotos";
 10
 11    private readonly IHttpClientFactory _httpClientFactory;
 12    private readonly IServerFileStorage _storage;
 13
 2714    public OzonHandoverPhotoStorage(IHttpClientFactory httpClientFactory, IServerFileStorage storage)
 15    {
 2716        _httpClientFactory = httpClientFactory;
 2717        _storage = storage;
 2718    }
 19
 20    public async Task<OzonHandoverStoredPhoto> DownloadAndStoreAsync(string sourceUrl, string batchKey, string itemKey,
 21        int sequence, CancellationToken cancellationToken = default)
 22    {
 2523        if (!Uri.TryCreate(sourceUrl, UriKind.Absolute, out var uri) || uri.Scheme != Uri.UriSchemeHttps)
 724            throw new InvalidOperationException("URL фотографии должен быть абсолютным HTTPS-адресом.");
 25
 1826        using var response = await _httpClientFactory.CreateClient(HttpClientName)
 1827            .GetAsync(uri, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
 1728        response.EnsureSuccessStatusCode();
 29
 1430        var contentType = response.Content.Headers.ContentType?.MediaType;
 1431        if (contentType is not null && !contentType.StartsWith("image/", StringComparison.OrdinalIgnoreCase))
 432            throw new InvalidOperationException("По URL фотографии получен не графический файл.");
 33
 1034        var extension = contentType?.ToLowerInvariant() switch
 1035        {
 336            "image/png" => ".png",
 237            "image/webp" => ".webp",
 138            "image/gif" => ".gif",
 439            _ => ".jpg"
 1040        };
 1041        var path = $"ozon-handover/photos/{Hash(batchKey)}/{Hash(itemKey)}/{sequence:D2}{extension}";
 1042        await using var content = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
 1043        await _storage.UploadAsync(new ServerFileUpload(path, content, contentType, Overwrite: true), cancellationToken)
 1044            .ConfigureAwait(false);
 1045        return new OzonHandoverStoredPhoto(path, contentType);
 1046    }
 47
 48    public async Task<Stream> OpenReadAsync(string storagePath, CancellationToken cancellationToken = default)
 49    {
 250        var download = await _storage.OpenReadAsync(storagePath, cancellationToken).ConfigureAwait(false);
 251        return download.Content;
 252    }
 53
 2054    private static string Hash(string value) => Convert.ToHexString(SHA256.HashData(System.Text.Encoding.UTF8.GetBytes(v
 55}