< Summary

Information
Class: Chronicis.Api.Controllers.CharactersController
Assembly: Chronicis.Api
File(s): /home/runner/work/chronicis/chronicis/src/Chronicis.Api/Controllers/CharactersController.cs
Line coverage
100%
Covered lines: 8
Uncovered lines: 0
Coverable lines: 8
Total lines: 111
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.Api/Controllers/CharactersController.cs

#LineLine coverage
 1using Chronicis.Api.Infrastructure;
 2using Chronicis.Api.Models;
 3using Chronicis.Api.Services;
 4using Chronicis.Shared.DTOs;
 5using Microsoft.AspNetCore.Authorization;
 6using Microsoft.AspNetCore.Mvc;
 7
 8namespace Chronicis.Api.Controllers;
 9
 10/// <summary>
 11/// API endpoints for Character claiming operations.
 12/// </summary>
 13[ApiController]
 14[Route("characters")]
 15[Authorize]
 16public class CharactersController : ControllerBase
 17{
 18    private readonly ICharacterClaimService _characterClaimService;
 19    private readonly ICurrentUserService _currentUserService;
 20    private readonly ILogger<CharactersController> _logger;
 21
 122    public CharactersController(
 123        ICharacterClaimService characterClaimService,
 124        ICurrentUserService currentUserService,
 125        ILogger<CharactersController> logger)
 26    {
 127        _characterClaimService = characterClaimService;
 128        _currentUserService = currentUserService;
 129        _logger = logger;
 130    }
 31
 32    /// <summary>
 33    /// GET /api/characters/claimed - Get all characters claimed by the current user.
 34    /// </summary>
 35    [HttpGet("claimed")]
 36    public async Task<ActionResult<List<ClaimedCharacterDto>>> GetClaimedCharacters()
 37    {
 38        var user = await _currentUserService.GetRequiredUserAsync();
 39        _logger.LogTraceSanitized("Getting claimed characters for user {UserId}", user.Id);
 40        var claimedCharacters = await _characterClaimService.GetClaimedCharactersAsync(user.Id);
 41        return Ok(claimedCharacters);
 42    }
 43
 44    /// <summary>
 45    /// GET /api/characters/{id}/claim - Get the claim status of a character.
 46    /// </summary>
 47    [HttpGet("{id:guid}/claim")]
 48    public async Task<ActionResult<CharacterClaimStatusDto>> GetClaimStatus(Guid id)
 49    {
 50        var user = await _currentUserService.GetRequiredUserAsync();
 51        _logger.LogTraceSanitized("Getting claim status for character {CharacterId}", id);
 52
 53        var result = await _characterClaimService.GetClaimStatusAsync(id);
 54        if (!result.Found)
 55        {
 56            return NotFound(new { error = "Character not found" });
 57        }
 58
 59        var status = new CharacterClaimStatusDto
 60        {
 61            CharacterId = id,
 62            IsClaimed = result.PlayerId.HasValue,
 63            IsClaimedByMe = result.PlayerId == user.Id,
 64            ClaimedByName = result.PlayerName
 65        };
 66
 67        return Ok(status);
 68    }
 69
 70    /// <summary>
 71    /// POST /api/characters/{id}/claim - Claim a character for the current user.
 72    /// </summary>
 73    [HttpPost("{id:guid}/claim")]
 74    public async Task<IActionResult> ClaimCharacter(Guid id)
 75    {
 76        var user = await _currentUserService.GetRequiredUserAsync();
 77        _logger.LogTraceSanitized("User {UserId} claiming character {CharacterId}", user.Id, id);
 78        var result = await _characterClaimService.ClaimCharacterAsync(id, user.Id);
 79        return result.Status switch
 80        {
 81            ServiceStatus.NotFound => NotFound(new { error = result.ErrorMessage }),
 82            ServiceStatus.Conflict => Conflict(new { error = result.ErrorMessage }),
 83            _ => NoContent()
 84        };
 85    }
 86
 87    /// <summary>
 88    /// DELETE /api/characters/{id}/claim - Unclaim a character (remove current user's claim).
 89    /// </summary>
 90    [HttpDelete("{id:guid}/claim")]
 91    public async Task<IActionResult> UnclaimCharacter(Guid id)
 92    {
 93        var user = await _currentUserService.GetRequiredUserAsync();
 94        _logger.LogTraceSanitized("User {UserId} unclaiming character {CharacterId}", user.Id, id);
 95        var result = await _characterClaimService.UnclaimCharacterAsync(id, user.Id);
 96        return result.Status == ServiceStatus.NotFound
 97            ? NotFound(new { error = result.ErrorMessage })
 98            : NoContent();
 99    }
 100}
 101
 102/// <summary>
 103/// Status of a character's claim.
 104/// </summary>
 105public class CharacterClaimStatusDto
 106{
 107    public Guid CharacterId { get; set; }
 108    public bool IsClaimed { get; set; }
 109    public bool IsClaimedByMe { get; set; }
 110    public string? ClaimedByName { get; set; }
 111}