< Summary

Information
Class: RaidLoop.Client.Services.GameActionApiClient
Assembly: RaidLoop.Client
File(s): /home/runner/work/RaidLoop/RaidLoop/src/RaidLoop.Client/Services/GameActionApiClient.cs
Line coverage
96%
Covered lines: 32
Uncovered lines: 1
Coverable lines: 33
Total lines: 65
Line coverage: 96.9%
Branch coverage
83%
Covered branches: 10
Total branches: 12
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()83.33%121295%
AuthorizeAsync()100%11100%

File(s)

/home/runner/work/RaidLoop/RaidLoop/src/RaidLoop.Client/Services/GameActionApiClient.cs

#LineLine coverage
 1using System.Net.Http.Headers;
 2using System.Net.Http.Json;
 3using System.Text.Json;
 4using RaidLoop.Client.Configuration;
 5using RaidLoop.Core.Contracts;
 6
 7namespace RaidLoop.Client.Services;
 8
 9public sealed class GameActionApiClient : IGameActionApiClient
 10{
 111    private static readonly JsonSerializerOptions JsonOptions = new(JsonSerializerDefaults.Web);
 12
 13    private readonly HttpClient _httpClient;
 14    private readonly ISupabaseSessionProvider _sessionProvider;
 15    private readonly string _publishableKey;
 16
 217    public GameActionApiClient(
 218        HttpClient httpClient,
 219        ISupabaseSessionProvider sessionProvider,
 220        SupabaseOptions options)
 21    {
 222        _httpClient = httpClient;
 223        _sessionProvider = sessionProvider;
 224        _publishableKey = options.PublishableKey;
 225    }
 26
 27    public async Task<GameActionResult> SendAsync(string action, object payload, CancellationToken cancellationToken = d
 28    {
 229        using var request = new HttpRequestMessage(HttpMethod.Post, "game-action")
 230        {
 231            Content = JsonContent.Create(new GameActionRequest(action, JsonSerializer.SerializeToElement(payload)), opti
 232        };
 33
 234        await AuthorizeAsync(request);
 35
 236        using var response = await _httpClient.SendAsync(request, cancellationToken);
 237        response.EnsureSuccessStatusCode();
 38
 239        var json = await response.Content.ReadAsStringAsync(cancellationToken);
 240        if (string.IsNullOrWhiteSpace(json))
 41        {
 042            throw new InvalidOperationException("Game action returned no payload.");
 43        }
 44
 245        using var document = JsonDocument.Parse(json);
 246        var root = document.RootElement;
 247        if (root.ValueKind != JsonValueKind.Object
 248            || (!root.TryGetProperty("eventType", out _)
 249                && !root.TryGetProperty("event", out _)
 250                && !root.TryGetProperty("projections", out _)))
 51        {
 152            throw new InvalidOperationException("Game action returned legacy snapshot payload.");
 53        }
 54
 155        var result = JsonSerializer.Deserialize<GameActionResult>(json, JsonOptions);
 156        return result ?? throw new InvalidOperationException("Game action returned no payload.");
 157    }
 58
 59    private async Task AuthorizeAsync(HttpRequestMessage request)
 60    {
 261        var accessToken = await _sessionProvider.GetAccessTokenAsync();
 262        request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
 263        request.Headers.Add("apikey", _publishableKey);
 264    }
 65}