< 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
92%
Covered lines: 35
Uncovered lines: 3
Coverable lines: 38
Total lines: 104
Line coverage: 92.1%
Branch coverage
100%
Covered branches: 8
Total branches: 8
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
CreateArticleFromAutocompleteAsync()100%2282.35%
FindWikiFolderAsync()100%66100%

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
 1328    public WikiLinkService(IArticleApiService articleApi, ILogger<WikiLinkService> logger)
 29    {
 1330        _articleApi = articleApi;
 1331        _logger = logger;
 1332    }
 33
 34    public async Task<ArticleDto?> CreateArticleFromAutocompleteAsync(string articleName, Guid worldId)
 35    {
 636        if (string.IsNullOrWhiteSpace(articleName))
 37        {
 338            return null;
 39        }
 40
 41        try
 42        {
 43            // Find the Wiki folder for this world
 344            Guid? wikiParentId = await FindWikiFolderAsync(worldId);
 45
 346            var createDto = new ArticleCreateDto
 347            {
 348                Title = articleName,
 349                Body = string.Empty,
 350                ParentId = wikiParentId,
 351                EffectiveDate = DateTime.Now,
 352                WorldId = worldId
 353            };
 54
 355            var created = await _articleApi.CreateArticleAsync(createDto);
 356            return created;
 57        }
 058        catch (Exception ex)
 59        {
 060            _logger.LogError(ex, "Error creating article from autocomplete: {Name}", articleName);
 061            return null;
 62        }
 663    }
 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
 1070            var rootArticles = await _articleApi.GetRootArticlesAsync(worldId);
 71
 872            if (rootArticles.Any())
 73            {
 674                var worldArticle = rootArticles.First();
 675                var worldChildren = await _articleApi.GetChildrenAsync(worldArticle.Id);
 76
 77                // Look for an article named "Wiki" (case-insensitive)
 678                var wikiFolder = worldChildren.FirstOrDefault(a =>
 1179                    a.Title.Equals("Wiki", StringComparison.OrdinalIgnoreCase));
 80
 681                if (wikiFolder != null)
 82                {
 483                    return wikiFolder.Id;
 84                }
 85            }
 86
 87            // Fallback: check if Wiki is at root level
 488            var rootWiki = rootArticles.FirstOrDefault(a =>
 789                a.Title.Equals("Wiki", StringComparison.OrdinalIgnoreCase));
 90
 491            if (rootWiki != null)
 92            {
 193                return rootWiki.Id;
 94            }
 95
 396            return null;
 97        }
 298        catch (Exception ex)
 99        {
 2100            _logger.LogError(ex, "Error finding Wiki folder for world {WorldId}", worldId);
 2101            return null;
 102        }
 10103    }
 104}