< Summary

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

#LineLine coverage
 1using Chronicis.Api.Infrastructure;
 2using Chronicis.Api.Services;
 3using Chronicis.Shared.DTOs;
 4using Microsoft.AspNetCore.Authorization;
 5using Microsoft.AspNetCore.Mvc;
 6
 7namespace Chronicis.Api.Controllers;
 8
 9/// <summary>
 10/// Controller for managing resource providers and their world associations.
 11/// </summary>
 12[ApiController]
 13[Route("api/worlds/{worldId}/resource-providers")]
 14[Authorize]
 15public class ResourceProvidersController : ControllerBase
 16{
 17    private readonly IResourceProviderService _service;
 18    private readonly ICurrentUserService _currentUserService;
 19    private readonly ILogger<ResourceProvidersController> _logger;
 20
 121    public ResourceProvidersController(
 122        IResourceProviderService service,
 123        ICurrentUserService currentUserService,
 124        ILogger<ResourceProvidersController> logger)
 25    {
 126        _service = service;
 127        _currentUserService = currentUserService;
 128        _logger = logger;
 129    }
 30
 31    /// <summary>
 32    /// Gets all resource providers with their enabled status for a world.
 33    /// </summary>
 34    /// <param name="worldId">The world ID</param>
 35    /// <returns>List of providers with enabled status</returns>
 36    [HttpGet]
 37    [ProducesResponseType(typeof(List<WorldResourceProviderDto>), StatusCodes.Status200OK)]
 38    [ProducesResponseType(StatusCodes.Status401Unauthorized)]
 39    [ProducesResponseType(StatusCodes.Status403Forbidden)]
 40    [ProducesResponseType(StatusCodes.Status404NotFound)]
 41    public async Task<IActionResult> GetWorldProviders(Guid worldId)
 42    {
 43        try
 44        {
 45            var user = await _currentUserService.GetRequiredUserAsync();
 46            var providers = await _service.GetWorldProvidersAsync(worldId, user.Id);
 47
 48            var dtos = providers.Select(p => new WorldResourceProviderDto
 49            {
 50                Provider = new ResourceProviderDto
 51                {
 52                    Code = p.Provider.Code,
 53                    Name = p.Provider.Name,
 54                    Description = p.Provider.Description,
 55                    DocumentationLink = p.Provider.DocumentationLink,
 56                    License = p.Provider.License
 57                },
 58                IsEnabled = p.IsEnabled,
 59                LookupKey = p.LookupKey
 60            }).ToList();
 61
 62            return Ok(dtos);
 63        }
 64        catch (KeyNotFoundException ex)
 65        {
 66            _logger.LogWarningSanitized(ex, "World {WorldId} not found", worldId);
 67            return NotFound(new { message = ex.Message });
 68        }
 69        catch (UnauthorizedAccessException ex)
 70        {
 71            _logger.LogWarningSanitized(ex, "Unauthorized access to world {WorldId}", worldId);
 72            return Forbid();
 73        }
 74    }
 75
 76    /// <summary>
 77    /// Enables or disables a resource provider for a world.
 78    /// Only the world owner can modify provider settings.
 79    /// </summary>
 80    /// <param name="worldId">The world ID</param>
 81    /// <param name="providerCode">The provider code</param>
 82    /// <param name="request">Toggle request</param>
 83    /// <returns>Success result</returns>
 84    [HttpPost("{providerCode}/toggle")]
 85    [ProducesResponseType(StatusCodes.Status200OK)]
 86    [ProducesResponseType(StatusCodes.Status401Unauthorized)]
 87    [ProducesResponseType(StatusCodes.Status403Forbidden)]
 88    [ProducesResponseType(StatusCodes.Status404NotFound)]
 89    public async Task<IActionResult> ToggleProvider(
 90        Guid worldId,
 91        string providerCode,
 92        [FromBody] ToggleResourceProviderRequestDto request)
 93    {
 94        try
 95        {
 96            var user = await _currentUserService.GetRequiredUserAsync();
 97            await _service.SetProviderEnabledAsync(worldId, providerCode, request.Enabled, user.Id, request.LookupKey);
 98
 99            return Ok(new { message = $"Provider {providerCode} {(request.Enabled ? "enabled" : "disabled")} successfull
 100        }
 101        catch (KeyNotFoundException ex)
 102        {
 103            _logger.LogErrorSanitized(ex, "World {WorldId} or provider {ProviderCode} not found", worldId, providerCode)
 104            return NotFound(new { message = ex.Message });
 105        }
 106        catch (UnauthorizedAccessException ex)
 107        {
 108            _logger.LogWarningSanitized(ex, "Unauthorized attempt to modify world {WorldId}", worldId);
 109            return Forbid();
 110        }
 111        catch (InvalidOperationException ex)
 112        {
 113            _logger.LogWarningSanitized(ex, "Invalid provider configuration for world {WorldId} and provider {ProviderCo
 114            return BadRequest(new { message = ex.Message });
 115        }
 116        catch (ArgumentException ex)
 117        {
 118            _logger.LogWarningSanitized(ex, "Invalid provider lookup key for world {WorldId} and provider {ProviderCode}
 119            return BadRequest(new { message = ex.Message });
 120        }
 121    }
 122}