< 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
0%
Covered lines: 0
Uncovered lines: 39
Coverable lines: 39
Total lines: 82
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 18
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%
GetSuggestionsAsync()0%2040%
GetBacklinksAsync()0%2040%
GetOutgoingLinksAsync()0%2040%
ResolveLinksAsync()0%4260%
AutoLinkAsync()100%210%

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
 014    public LinkApiService(HttpClient http, ILogger<LinkApiService> logger)
 15    {
 016        _http = http;
 017        _logger = logger;
 018    }
 19
 20    public async Task<List<LinkSuggestionDto>> GetSuggestionsAsync(Guid worldId, string query)
 21    {
 22        // Response is wrapped in LinkSuggestionsResponseDto
 023        var response = await _http.GetEntityAsync<LinkSuggestionsResponseDto>(
 024            $"worlds/{worldId}/link-suggestions?query={Uri.EscapeDataString(query)}",
 025            _logger,
 026            $"link suggestions for world {worldId}");
 27
 028        return response?.Suggestions ?? new List<LinkSuggestionDto>();
 029    }
 30
 31    public async Task<List<BacklinkDto>> GetBacklinksAsync(Guid articleId)
 32    {
 33        // Response is wrapped in BacklinksResponseDto
 034        var response = await _http.GetEntityAsync<BacklinksResponseDto>(
 035            $"articles/{articleId}/backlinks",
 036            _logger,
 037            $"backlinks for article {articleId}");
 38
 039        return response?.Backlinks ?? new List<BacklinkDto>();
 040    }
 41
 42    public async Task<List<BacklinkDto>> GetOutgoingLinksAsync(Guid articleId)
 43    {
 44        // Response is wrapped in BacklinksResponseDto
 045        var response = await _http.GetEntityAsync<BacklinksResponseDto>(
 046            $"articles/{articleId}/outgoing-links",
 047            _logger,
 048            $"outgoing links for article {articleId}");
 49
 050        return response?.Backlinks ?? new List<BacklinkDto>();
 051    }
 52
 53    public async Task<Dictionary<Guid, ResolvedLinkDto>> ResolveLinksAsync(List<Guid> articleIds)
 54    {
 055        if (!articleIds.Any())
 56        {
 057            return new Dictionary<Guid, ResolvedLinkDto>();
 58        }
 59
 060        var request = new LinkResolutionRequestDto { ArticleIds = articleIds };
 61
 62        // Response is wrapped in LinkResolutionResponseDto
 063        var response = await _http.PostEntityAsync<LinkResolutionResponseDto>(
 064            "articles/resolve-links",
 065            request,
 066            _logger,
 067            $"resolution for {articleIds.Count} links");
 68
 069        return response?.Articles ?? new Dictionary<Guid, ResolvedLinkDto>();
 070    }
 71
 72    public async Task<AutoLinkResponseDto?> AutoLinkAsync(Guid articleId, string body)
 73    {
 074        var request = new AutoLinkRequestDto { Body = body };
 75
 076        return await _http.PostEntityAsync<AutoLinkResponseDto>(
 077            $"articles/{articleId}/auto-link",
 078            request,
 079            _logger,
 080            $"auto-link for article {articleId}");
 081    }
 82}