< Summary

Information
Class: Chronicis.Client.Services.WikiLinkService
Assembly: Chronicis.Client
File(s): /home/runner/work/chronicis/chronicis/src/Chronicis.Client/Services/WikiLinkService.cs
Line coverage
100%
Covered lines: 3
Uncovered lines: 0
Coverable lines: 3
Total lines: 104
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/WikiLinkService.cs

#LineLine coverage
 1using Chronicis.Shared.DTOs;
 2
 3namespace Chronicis.Client.Services;
 4
 5/// <summary>
 6/// Service for wiki link operations including creating articles from autocomplete
 7/// and finding wiki folder locations.
 8/// </summary>
 9public interface IWikiLinkService
 10{
 11    /// <summary>
 12    /// Creates a new article from autocomplete and returns it.
 13    /// The article is created in the Wiki folder if one exists.
 14    /// </summary>
 15    Task<ArticleDto?> CreateArticleFromAutocompleteAsync(string articleName, Guid worldId);
 16
 17    /// <summary>
 18    /// Finds the Wiki folder for a given world.
 19    /// </summary>
 20    Task<Guid?> FindWikiFolderAsync(Guid worldId);
 21}
 22
 23public class WikiLinkService : IWikiLinkService
 24{
 25    private readonly IArticleApiService _articleApi;
 26    private readonly ILogger<WikiLinkService> _logger;
 27
 28    public WikiLinkService(IArticleApiService articleApi, ILogger<WikiLinkService> logger)
 29    {
 1430        _articleApi = articleApi;
 1431        _logger = logger;
 1432    }
 33
 34    public async Task<ArticleDto?> CreateArticleFromAutocompleteAsync(string articleName, Guid worldId)
 35    {
 36        if (string.IsNullOrWhiteSpace(articleName))
 37        {
 38            return null;
 39        }
 40
 41        try
 42        {
 43            // Find the Wiki folder for this world
 44            Guid? wikiParentId = await FindWikiFolderAsync(worldId);
 45
 46            var createDto = new ArticleCreateDto
 47            {
 48                Title = articleName,
 49                Body = string.Empty,
 50                ParentId = wikiParentId,
 51                EffectiveDate = DateTime.Now,
 52                WorldId = worldId
 53            };
 54
 55            var created = await _articleApi.CreateArticleAsync(createDto);
 56            return created;
 57        }
 58        catch (Exception ex)
 59        {
 60            _logger.LogError(ex, "Error creating article from autocomplete: {Name}", articleName);
 61            return null;
 62        }
 63    }
 64
 65    public async Task<Guid?> FindWikiFolderAsync(Guid worldId)
 66    {
 67        try
 68        {
 69            // The Wiki folder is typically a child of the World article
 70            var rootArticles = await _articleApi.GetRootArticlesAsync(worldId);
 71
 72            if (rootArticles.Any())
 73            {
 74                var worldArticle = rootArticles.First();
 75                var worldChildren = await _articleApi.GetChildrenAsync(worldArticle.Id);
 76
 77                // Look for an article named "Wiki" (case-insensitive)
 78                var wikiFolder = worldChildren.FirstOrDefault(a =>
 79                    a.Title.Equals("Wiki", StringComparison.OrdinalIgnoreCase));
 80
 81                if (wikiFolder != null)
 82                {
 83                    return wikiFolder.Id;
 84                }
 85            }
 86
 87            // Fallback: check if Wiki is at root level
 88            var rootWiki = rootArticles.FirstOrDefault(a =>
 89                a.Title.Equals("Wiki", StringComparison.OrdinalIgnoreCase));
 90
 91            if (rootWiki != null)
 92            {
 93                return rootWiki.Id;
 94            }
 95
 96            return null;
 97        }
 98        catch (Exception ex)
 99        {
 100            _logger.LogError(ex, "Error finding Wiki folder for world {WorldId}", worldId);
 101            return null;
 102        }
 103    }
 104}