< Summary

Information
Class: Chronicis.Api.Controllers.QuestsController
Assembly: Chronicis.Api
File(s): /home/runner/work/chronicis/chronicis/src/Chronicis.Api/Controllers/QuestsController.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 78
Coverable lines: 78
Total lines: 154
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 28
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%
GetQuestsByArc()0%2040%
CreateQuest()0%7280%
GetQuest()0%2040%
UpdateQuest()0%7280%
DeleteQuest()0%2040%

File(s)

/home/runner/work/chronicis/chronicis/src/Chronicis.Api/Controllers/QuestsController.cs

#LineLine coverage
 1using Chronicis.Api.Infrastructure;
 2using Chronicis.Api.Models;
 3using Chronicis.Api.Services;
 4using Chronicis.Shared.DTOs.Quests;
 5using Chronicis.Shared.Extensions;
 6using Microsoft.AspNetCore.Authorization;
 7using Microsoft.AspNetCore.Mvc;
 8
 9namespace Chronicis.Api.Controllers;
 10
 11/// <summary>
 12/// API endpoints for Quest management.
 13/// </summary>
 14[ApiController]
 15[Authorize]
 16public class QuestsController : ControllerBase
 17{
 18    private readonly IQuestService _questService;
 19    private readonly ICurrentUserService _currentUserService;
 20    private readonly ILogger<QuestsController> _logger;
 21
 022    public QuestsController(
 023        IQuestService questService,
 024        ICurrentUserService currentUserService,
 025        ILogger<QuestsController> logger)
 26    {
 027        _questService = questService;
 028        _currentUserService = currentUserService;
 029        _logger = logger;
 030    }
 31
 32    /// <summary>
 33    /// GET /arcs/{arcId}/quests - Get all quests for an arc.
 34    /// </summary>
 35    [HttpGet("arcs/{arcId:guid}/quests")]
 36    public async Task<ActionResult<List<QuestDto>>> GetQuestsByArc(Guid arcId)
 37    {
 038        var user = await _currentUserService.GetRequiredUserAsync();
 039        _logger.LogDebug("Getting quests for arc {ArcId} for user {UserId}", arcId, user.Id);
 40
 041        var result = await _questService.GetQuestsByArcAsync(arcId, user.Id);
 42
 043        return result.Status switch
 044        {
 045            ServiceStatus.Success => Ok(result.Value),
 046            ServiceStatus.NotFound => NotFound(new { error = result.ErrorMessage }),
 047            ServiceStatus.Forbidden => StatusCode(403, new { error = result.ErrorMessage }),
 048            _ => StatusCode(500, new { error = "An unexpected error occurred" })
 049        };
 050    }
 51
 52    /// <summary>
 53    /// POST /arcs/{arcId}/quests - Create a new quest (GM only).
 54    /// </summary>
 55    [HttpPost("arcs/{arcId:guid}/quests")]
 56    public async Task<ActionResult<QuestDto>> CreateQuest(Guid arcId, [FromBody] QuestCreateDto dto)
 57    {
 058        var user = await _currentUserService.GetRequiredUserAsync();
 59
 060        if (dto == null)
 61        {
 062            return BadRequest(new { error = "Request body is required" });
 63        }
 64
 065        _logger.LogDebugSanitized("Creating quest '{Title}' in arc {ArcId} for user {UserId}",
 066            dto.Title, arcId, user.Id);
 67
 068        var result = await _questService.CreateQuestAsync(arcId, dto, user.Id);
 69
 070        return result.Status switch
 071        {
 072            ServiceStatus.Success => CreatedAtAction(
 073                nameof(GetQuest),
 074                new { questId = result.Value!.Id },
 075                result.Value),
 076            ServiceStatus.NotFound => NotFound(new { error = result.ErrorMessage }),
 077            ServiceStatus.Forbidden => StatusCode(403, new { error = result.ErrorMessage }),
 078            ServiceStatus.ValidationError => BadRequest(new { error = result.ErrorMessage }),
 079            _ => StatusCode(500, new { error = "An unexpected error occurred" })
 080        };
 081    }
 82
 83    /// <summary>
 84    /// GET /quests/{questId} - Get a specific quest with update count.
 85    /// </summary>
 86    [HttpGet("quests/{questId:guid}")]
 87    public async Task<ActionResult<QuestDto>> GetQuest(Guid questId)
 88    {
 089        var user = await _currentUserService.GetRequiredUserAsync();
 090        _logger.LogDebug("Getting quest {QuestId} for user {UserId}", questId, user.Id);
 91
 092        var result = await _questService.GetQuestAsync(questId, user.Id);
 93
 094        return result.Status switch
 095        {
 096            ServiceStatus.Success => Ok(result.Value),
 097            ServiceStatus.NotFound => NotFound(new { error = result.ErrorMessage }),
 098            ServiceStatus.Forbidden => StatusCode(403, new { error = result.ErrorMessage }),
 099            _ => StatusCode(500, new { error = "An unexpected error occurred" })
 0100        };
 0101    }
 102
 103    /// <summary>
 104    /// PUT /quests/{questId} - Update a quest (GM only). Includes RowVersion concurrency check.
 105    /// </summary>
 106    [HttpPut("quests/{questId:guid}")]
 107    public async Task<ActionResult<QuestDto>> UpdateQuest(Guid questId, [FromBody] QuestEditDto dto)
 108    {
 0109        var user = await _currentUserService.GetRequiredUserAsync();
 110
 0111        if (dto == null)
 112        {
 0113            return BadRequest(new { error = "Request body is required" });
 114        }
 115
 0116        _logger.LogDebug("Updating quest {QuestId} for user {UserId}", questId, user.Id);
 117
 0118        var result = await _questService.UpdateQuestAsync(questId, dto, user.Id);
 119
 0120        return result.Status switch
 0121        {
 0122            ServiceStatus.Success => Ok(result.Value),
 0123            ServiceStatus.NotFound => NotFound(new { error = result.ErrorMessage }),
 0124            ServiceStatus.Forbidden => StatusCode(403, new { error = result.ErrorMessage }),
 0125            ServiceStatus.Conflict => Conflict(new
 0126            {
 0127                error = result.ErrorMessage,
 0128                currentState = result.Value // Include current QuestDto with latest RowVersion
 0129            }),
 0130            ServiceStatus.ValidationError => BadRequest(new { error = result.ErrorMessage }),
 0131            _ => StatusCode(500, new { error = "An unexpected error occurred" })
 0132        };
 0133    }
 134
 135    /// <summary>
 136    /// DELETE /quests/{questId} - Delete a quest and all its updates (GM only).
 137    /// </summary>
 138    [HttpDelete("quests/{questId:guid}")]
 139    public async Task<IActionResult> DeleteQuest(Guid questId)
 140    {
 0141        var user = await _currentUserService.GetRequiredUserAsync();
 0142        _logger.LogDebug("Deleting quest {QuestId} for user {UserId}", questId, user.Id);
 143
 0144        var result = await _questService.DeleteQuestAsync(questId, user.Id);
 145
 0146        return result.Status switch
 0147        {
 0148            ServiceStatus.Success => NoContent(),
 0149            ServiceStatus.NotFound => NotFound(new { error = result.ErrorMessage }),
 0150            ServiceStatus.Forbidden => StatusCode(403, new { error = result.ErrorMessage }),
 0151            _ => StatusCode(500, new { error = "An unexpected error occurred" })
 0152        };
 0153    }
 154}