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()); } }