< Summary

Information
Class: Chronicis.Client.Services.PublicApiService
Assembly: Chronicis.Client
File(s): /home/runner/work/chronicis/chronicis/src/Chronicis.Client/Services/PublicApiService.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 54
Coverable lines: 54
Total lines: 127
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 16
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%210%
GetPublicWorldAsync()0%2040%
GetPublicArticleTreeAsync()0%2040%
GetPublicArticleAsync()0%2040%
ResolvePublicArticlePathAsync()0%2040%

File(s)

/home/runner/work/chronicis/chronicis/src/Chronicis.Client/Services/PublicApiService.cs

#LineLine coverage
 1using System.Net.Http.Json;
 2using Chronicis.Shared.DTOs;
 3
 4namespace Chronicis.Client.Services;
 5
 6/// <summary>
 7/// Service for anonymous public API operations.
 8/// Uses a separate HttpClient without authentication headers.
 9/// </summary>
 10public class PublicApiService : IPublicApiService
 11{
 12    private readonly HttpClient _http;
 13    private readonly ILogger<PublicApiService> _logger;
 14
 015    public PublicApiService(HttpClient http, ILogger<PublicApiService> logger)
 16    {
 017        _http = http;
 018        _logger = logger;
 019    }
 20
 21    public async Task<WorldDetailDto?> GetPublicWorldAsync(string publicSlug)
 22    {
 23        try
 24        {
 025            var response = await _http.GetAsync($"public/worlds/{publicSlug}");
 26
 027            if (response.IsSuccessStatusCode)
 28            {
 029                return await response.Content.ReadFromJsonAsync<WorldDetailDto>();
 30            }
 31
 032            if (response.StatusCode == System.Net.HttpStatusCode.NotFound)
 33            {
 034                _logger.LogDebug("Public world not found: {PublicSlug}", publicSlug);
 035                return null;
 36            }
 37
 038            _logger.LogWarning("Failed to get public world {PublicSlug}: {StatusCode}",
 039                publicSlug, response.StatusCode);
 040            return null;
 41        }
 042        catch (Exception ex)
 43        {
 044            _logger.LogError(ex, "Error getting public world {PublicSlug}", publicSlug);
 045            return null;
 46        }
 047    }
 48
 49    public async Task<List<ArticleTreeDto>> GetPublicArticleTreeAsync(string publicSlug)
 50    {
 51        try
 52        {
 053            var response = await _http.GetAsync($"public/worlds/{publicSlug}/articles");
 54
 055            if (response.IsSuccessStatusCode)
 56            {
 057                return await response.Content.ReadFromJsonAsync<List<ArticleTreeDto>>()
 058                    ?? new List<ArticleTreeDto>();
 59            }
 60
 061            _logger.LogWarning("Failed to get public article tree for {PublicSlug}: {StatusCode}",
 062                publicSlug, response.StatusCode);
 063            return new List<ArticleTreeDto>();
 64        }
 065        catch (Exception ex)
 66        {
 067            _logger.LogError(ex, "Error getting public article tree for {PublicSlug}", publicSlug);
 068            return new List<ArticleTreeDto>();
 69        }
 070    }
 71
 72    public async Task<ArticleDto?> GetPublicArticleAsync(string publicSlug, string articlePath)
 73    {
 74        try
 75        {
 076            var response = await _http.GetAsync($"public/worlds/{publicSlug}/articles/{articlePath}");
 77
 078            if (response.IsSuccessStatusCode)
 79            {
 080                return await response.Content.ReadFromJsonAsync<ArticleDto>();
 81            }
 82
 083            if (response.StatusCode == System.Net.HttpStatusCode.NotFound)
 84            {
 085                _logger.LogDebug("Public article not found: {PublicSlug}/{ArticlePath}", publicSlug, articlePath);
 086                return null;
 87            }
 88
 089            _logger.LogWarning("Failed to get public article {PublicSlug}/{ArticlePath}: {StatusCode}",
 090                publicSlug, articlePath, response.StatusCode);
 091            return null;
 92        }
 093        catch (Exception ex)
 94        {
 095            _logger.LogError(ex, "Error getting public article {PublicSlug}/{ArticlePath}", publicSlug, articlePath);
 096            return null;
 97        }
 098    }
 99
 100    public async Task<string?> ResolvePublicArticlePathAsync(string publicSlug, Guid articleId)
 101    {
 102        try
 103        {
 0104            var response = await _http.GetAsync($"public/worlds/{publicSlug}/articles/resolve/{articleId}");
 105
 0106            if (response.IsSuccessStatusCode)
 107            {
 0108                return await response.Content.ReadAsStringAsync();
 109            }
 110
 0111            if (response.StatusCode == System.Net.HttpStatusCode.NotFound)
 112            {
 0113                _logger.LogDebug("Public article path not found: {PublicSlug}/{ArticleId}", publicSlug, articleId);
 0114                return null;
 115            }
 116
 0117            _logger.LogWarning("Failed to resolve public article path {PublicSlug}/{ArticleId}: {StatusCode}",
 0118                publicSlug, articleId, response.StatusCode);
 0119            return null;
 120        }
 0121        catch (Exception ex)
 122        {
 0123            _logger.LogError(ex, "Error resolving public article path {PublicSlug}/{ArticleId}", publicSlug, articleId);
 0124            return null;
 125        }
 0126    }
 127}