< Summary

Information
Class: Chronicis.Client.Services.LinkApiService
Assembly: Chronicis.Client
File(s): /home/runner/work/chronicis/chronicis/src/Chronicis.Client/Services/LinkApiService.cs
Line coverage
100%
Covered lines: 3
Uncovered lines: 0
Coverable lines: 3
Total lines: 82
Line coverage: 100%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%

File(s)

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

#LineLine coverage
 1using Chronicis.Shared.DTOs;
 2
 3namespace Chronicis.Client.Services;
 4
 5/// <summary>
 6/// Client service for interacting with wiki link APIs.
 7/// Uses HttpClientExtensions where applicable, with custom handling for wrapped responses.
 8/// </summary>
 9public class LinkApiService : ILinkApiService
 10{
 11    private readonly HttpClient _http;
 12    private readonly ILogger<LinkApiService> _logger;
 13
 14    public LinkApiService(HttpClient http, ILogger<LinkApiService> logger)
 15    {
 316        _http = http;
 317        _logger = logger;
 318    }
 19
 20    public async Task<List<LinkSuggestionDto>> GetSuggestionsAsync(Guid worldId, string query)
 21    {
 22        // Response is wrapped in LinkSuggestionsResponseDto
 23        var response = await _http.GetEntityAsync<LinkSuggestionsResponseDto>(
 24            $"worlds/{worldId}/link-suggestions?query={Uri.EscapeDataString(query)}",
 25            _logger,
 26            $"link suggestions for world {worldId}");
 27
 28        return response?.Suggestions ?? new List<LinkSuggestionDto>();
 29    }
 30
 31    public async Task<List<BacklinkDto>> GetBacklinksAsync(Guid articleId)
 32    {
 33        // Response is wrapped in BacklinksResponseDto
 34        var response = await _http.GetEntityAsync<BacklinksResponseDto>(
 35            $"articles/{articleId}/backlinks",
 36            _logger,
 37            $"backlinks for article {articleId}");
 38
 39        return response?.Backlinks ?? new List<BacklinkDto>();
 40    }
 41
 42    public async Task<List<BacklinkDto>> GetOutgoingLinksAsync(Guid articleId)
 43    {
 44        // Response is wrapped in BacklinksResponseDto
 45        var response = await _http.GetEntityAsync<BacklinksResponseDto>(
 46            $"articles/{articleId}/outgoing-links",
 47            _logger,
 48            $"outgoing links for article {articleId}");
 49
 50        return response?.Backlinks ?? new List<BacklinkDto>();
 51    }
 52
 53    public async Task<Dictionary<Guid, ResolvedLinkDto>> ResolveLinksAsync(List<Guid> articleIds)
 54    {
 55        if (!articleIds.Any())
 56        {
 57            return new Dictionary<Guid, ResolvedLinkDto>();
 58        }
 59
 60        var request = new LinkResolutionRequestDto { ArticleIds = articleIds };
 61
 62        // Response is wrapped in LinkResolutionResponseDto
 63        var response = await _http.PostEntityAsync<LinkResolutionResponseDto>(
 64            "articles/resolve-links",
 65            request,
 66            _logger,
 67            $"resolution for {articleIds.Count} links");
 68
 69        return response?.Articles ?? new Dictionary<Guid, ResolvedLinkDto>();
 70    }
 71
 72    public async Task<AutoLinkResponseDto?> AutoLinkAsync(Guid articleId, string body)
 73    {
 74        var request = new AutoLinkRequestDto { Body = body };
 75
 76        return await _http.PostEntityAsync<AutoLinkResponseDto>(
 77            $"articles/{articleId}/auto-link",
 78            request,
 79            _logger,
 80            $"auto-link for article {articleId}");
 81    }
 82}