using System.Text.Json;
using ColaFlow.Modules.Mcp.Application.Resources;
using ColaFlow.Modules.Mcp.Contracts.Resources;
using ColaFlow.Modules.ProjectManagement.Application.Common.Interfaces;
using ColaFlow.Modules.ProjectManagement.Domain.Aggregates.ProjectAggregate;
using ColaFlow.Modules.ProjectManagement.Domain.Enums;
using ColaFlow.Modules.ProjectManagement.Domain.Repositories;
using ColaFlow.Modules.ProjectManagement.Domain.ValueObjects;
using FluentAssertions;
using Microsoft.Extensions.Logging;
using NSubstitute;
namespace ColaFlow.Modules.Mcp.Tests.Resources;
///
/// Unit tests for ProjectsListResource
///
public class ProjectsListResourceTests
{
private readonly IProjectRepository _projectRepository;
private readonly ITenantContext _tenantContext;
private readonly ILogger _logger;
private readonly ProjectsListResource _sut;
private readonly Guid _tenantId = Guid.NewGuid();
public ProjectsListResourceTests()
{
_projectRepository = Substitute.For();
_tenantContext = Substitute.For();
_logger = Substitute.For>();
_tenantContext.GetCurrentTenantId().Returns(_tenantId);
_sut = new ProjectsListResource(_projectRepository, _tenantContext, _logger);
}
[Fact]
public void Uri_ReturnsCorrectValue()
{
// Assert
_sut.Uri.Should().Be("colaflow://projects.list");
}
[Fact]
public void Name_ReturnsCorrectValue()
{
// Assert
_sut.Name.Should().Be("Projects List");
}
[Fact]
public void MimeType_ReturnsApplicationJson()
{
// Assert
_sut.MimeType.Should().Be("application/json");
}
[Fact]
public async Task GetContentAsync_WithNoProjects_ReturnsEmptyList()
{
// Arrange
_projectRepository.GetAllProjectsReadOnlyAsync(Arg.Any())
.Returns(new List());
var request = new McpResourceRequest { Uri = "colaflow://projects.list" };
// Act
var result = await _sut.GetContentAsync(request, CancellationToken.None);
// Assert
result.Should().NotBeNull();
result.Uri.Should().Be("colaflow://projects.list");
result.MimeType.Should().Be("application/json");
var data = JsonSerializer.Deserialize(result.Text);
data.GetProperty("projects").GetArrayLength().Should().Be(0);
data.GetProperty("total").GetInt32().Should().Be(0);
}
[Fact]
public async Task GetContentAsync_WithProjects_ReturnsProjectsList()
{
// Arrange
var project1 = Project.Create(
ColaFlow.Modules.ProjectManagement.Domain.ValueObjects.TenantId.From(_tenantId),
"Project Alpha",
"First project",
"ALPHA",
UserId.Create());
var project2 = Project.Create(
ColaFlow.Modules.ProjectManagement.Domain.ValueObjects.TenantId.From(_tenantId),
"Project Beta",
"Second project",
"BETA",
UserId.Create());
_projectRepository.GetAllProjectsReadOnlyAsync(Arg.Any())
.Returns(new List { project1, project2 });
var request = new McpResourceRequest { Uri = "colaflow://projects.list" };
// Act
var result = await _sut.GetContentAsync(request, CancellationToken.None);
// Assert
result.Should().NotBeNull();
var data = JsonSerializer.Deserialize(result.Text);
data.GetProperty("total").GetInt32().Should().Be(2);
var projects = data.GetProperty("projects");
projects.GetArrayLength().Should().Be(2);
var firstProject = projects[0];
firstProject.GetProperty("name").GetString().Should().Be("Project Alpha");
firstProject.GetProperty("key").GetString().Should().Be("ALPHA");
firstProject.GetProperty("status").GetString().Should().Be(ProjectStatus.Active.ToString());
}
[Fact]
public async Task GetContentAsync_CallsTenantContext()
{
// Arrange
_projectRepository.GetAllProjectsReadOnlyAsync(Arg.Any())
.Returns(new List());
var request = new McpResourceRequest { Uri = "colaflow://projects.list" };
// Act
await _sut.GetContentAsync(request, CancellationToken.None);
// Assert
_tenantContext.Received(1).GetCurrentTenantId();
}
[Fact]
public async Task GetContentAsync_CallsRepository()
{
// Arrange
_projectRepository.GetAllProjectsReadOnlyAsync(Arg.Any())
.Returns(new List());
var request = new McpResourceRequest { Uri = "colaflow://projects.list" };
// Act
await _sut.GetContentAsync(request, CancellationToken.None);
// Assert
await _projectRepository.Received(1).GetAllProjectsReadOnlyAsync(Arg.Any());
}
}