< Summary - ZhEaIsNsAaBn.Libraries coverage (affected: 23 packages)

Information
Class: ZhEaIsNsAaBn.IntegrationTestingBases.HttpTestUtilities
Assembly: ZhEaIsNsAaBn.IntegrationTestingBases
File(s): /home/runner/work/ZhEaIsNsAaBn.Libraries.V1/ZhEaIsNsAaBn.Libraries.V1/src/TestPackages/ZhEaIsNsAaBn.IntegrationTestingBases/Utilities/HttpTestUtilities.cs
Line coverage
94%
Covered lines: 18
Uncovered lines: 1
Coverable lines: 19
Total lines: 78
Line coverage: 94.7%
Branch coverage
100%
Covered branches: 4
Total branches: 4
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.cctor()100%11100%
ToJsonContent(...)100%11100%
ReadResponseAsync()100%44100%
ReadResponseAsStringAsync(...)100%210%
CreateMultipartContent()100%11100%
AddFileToMultipart(...)100%11100%
AddFormFieldToMultipart(...)100%11100%

File(s)

/home/runner/work/ZhEaIsNsAaBn.Libraries.V1/ZhEaIsNsAaBn.Libraries.V1/src/TestPackages/ZhEaIsNsAaBn.IntegrationTestingBases/Utilities/HttpTestUtilities.cs

#LineLine coverage
 1#region Usings
 2using System.Net.Http.Headers;
 3#endregion
 4
 5namespace ZhEaIsNsAaBn.IntegrationTestingBases;
 6
 7/// <summary>HTTP helpers for integration tests: JSON request bodies, response reading and multipart uploads.</summary>
 8public static class HttpTestUtilities
 9{
 310    private static readonly JsonSerializerOptions _jsonOptions = new()
 311                                                                 {
 312                                                                     PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
 313                                                                     WriteIndented        = true
 314                                                                 };
 15
 16
 17    /// <summary>Serializes <paramref name="obj"/> to camelCase JSON content.</summary>
 18    /// <typeparam name="T">The value type.</typeparam>
 19    /// <param name="obj">The value to send.</param>
 20    /// <returns><c>application/json</c> content in UTF-8. The caller disposes it.</returns>
 21    public static StringContent ToJsonContent< T >( T obj )
 622        => new( JsonSerializer.Serialize( obj, _jsonOptions ), Encoding.UTF8, "application/json" );
 23
 24    /// <summary>Reads and deserializes a JSON response (camelCase names).</summary>
 25    /// <typeparam name="T">The expected body type.</typeparam>
 26    /// <param name="response">The response to read.</param>
 27    /// <param name="cancellationToken">Token to cancel the operation.</param>
 28    /// <returns>The deserialized body.</returns>
 29    /// <exception cref="InvalidOperationException">The body is empty, <c>null</c> or not valid JSON for <typeparamref n
 30    public static async Task<T> ReadResponseAsync< T >( HttpResponseMessage response, CancellationToken cancellationToke
 31    {
 1832        var content = await response.Content.ReadAsStringAsync( cancellationToken ).ConfigureAwait( false );
 33
 2134        if ( string.IsNullOrEmpty( content ) ) { throw new InvalidOperationException( "Response content is empty" ); }
 35
 36
 37        try
 38        {
 1539            return JsonSerializer.Deserialize<T>( content, _jsonOptions ) ?? throw new InvalidOperationException( "Deser
 40        }
 341        catch ( JsonException ex )
 42        {
 343            throw new InvalidOperationException( $"Failed to deserialize response. Content: {content}", ex );
 44        }
 945    }
 46
 47    /// <summary>Reads the response body as a string.</summary>
 48    /// <param name="response">The response to read.</param>
 49    /// <param name="cancellationToken">Token to cancel the operation.</param>
 50    /// <returns>The body.</returns>
 51    public static Task<string> ReadResponseAsStringAsync( HttpResponseMessage response, CancellationToken cancellationTo
 052        => response.Content.ReadAsStringAsync( cancellationToken );
 53
 54    /// <summary>Creates empty multipart form-data content for uploads.</summary>
 55    /// <returns>New multipart content. The caller disposes it.</returns>
 356    public static MultipartFormDataContent CreateMultipartContent() => new();
 57
 58    /// <summary>Adds a file (<c>application/octet-stream</c>) to multipart content.</summary>
 59    /// <param name="content">The multipart content.</param>
 60    /// <param name="fileBytes">The file bytes.</param>
 61    /// <param name="fileName">The file name sent to the server.</param>
 62    /// <param name="fieldName">The form field name. Default: <c>file</c>.</param>
 63    public static void AddFileToMultipart( MultipartFormDataContent content, byte[] fileBytes, string fileName, string f
 64    {
 365        var fileContent = new ByteArrayContent( fileBytes );
 366        fileContent.Headers.ContentType = new MediaTypeHeaderValue( "application/octet-stream" );
 67
 68
 369        content.Add( fileContent, fieldName, fileName );
 370    }
 71
 72    /// <summary>Adds a text field to multipart content.</summary>
 73    /// <param name="content">The multipart content.</param>
 74    /// <param name="name">The field name.</param>
 75    /// <param name="value">The field value.</param>
 76    public static void AddFormFieldToMultipart( MultipartFormDataContent content, string name, string value )
 377        => content.Add( new StringContent( value ), name );
 78}