节点在线、应用在线、配置在线使用令牌查询
大石头 authored at 2021-12-16 19:49:30
6.70 KiB
Stardust
using Stardust.Data.Platform;
using Xunit;

namespace ServerTest.Mcp;

/// <summary>MCP令牌资源授权单元测试。覆盖授权判定逻辑、IsAll语义、项目ID解析</summary>
public class McpTokenResourceTests
{
    /// <summary>模拟授权列表,用于内联测试 IsAuthorized 的判定逻辑</summary>
    private static Boolean IsAuthorizedInline(IList<McpTokenResource> list, String resourceType, Int32 resourceId)
    {
        foreach (var r in list)
        {
            if (!r.Enable) continue;
            if (r.ResourceType != resourceType) continue;
            if (r.IsAll) return true;
            if (r.ResourceId == resourceId) return true;
        }
        return false;
    }

    /// <summary>模拟 GetAuthorizedProjectIds 的判定逻辑</summary>
    private static Int32[] GetAuthorizedProjectIdsInline(IList<McpTokenResource> list)
    {
        var ids = new List<Int32>();
        foreach (var r in list.Where(r => r.Enable && r.ResourceType == McpResourceType.Project.ToStorageName()))
        {
            if (r.IsAll) return null; // null 表示全部
            ids.Add(r.ResourceId);
        }
        return ids.Count > 0 ? ids.Distinct().ToArray() : Array.Empty<Int32>();
    }

    [Fact]
    public void IsAuthorized_DirectMatch_ReturnsTrue()
    {
        var list = new List<McpTokenResource>
        {
            new() { Enable = true, ResourceType = McpResourceType.Node.ToStorageName(), ResourceId = 100, IsAll = false }
        };

        Assert.True(IsAuthorizedInline(list, McpResourceType.Node.ToStorageName(), 100));
    }

    [Fact]
    public void IsAuthorized_NoMatch_ReturnsFalse()
    {
        var list = new List<McpTokenResource>
        {
            new() { Enable = true, ResourceType = McpResourceType.Node.ToStorageName(), ResourceId = 100, IsAll = false }
        };

        Assert.False(IsAuthorizedInline(list, McpResourceType.Node.ToStorageName(), 200));
    }

    [Fact]
    public void IsAuthorized_IsAll_ReturnsTrue()
    {
        var list = new List<McpTokenResource>
        {
            new() { Enable = true, ResourceType = McpResourceType.Node.ToStorageName(), ResourceId = 0, IsAll = true }
        };

        Assert.True(IsAuthorizedInline(list, McpResourceType.Node.ToStorageName(), 999));
    }

    [Fact]
    public void IsAuthorized_Disabled_ReturnsFalse()
    {
        var list = new List<McpTokenResource>
        {
            new() { Enable = false, ResourceType = McpResourceType.Node.ToStorageName(), ResourceId = 100, IsAll = false }
        };

        Assert.False(IsAuthorizedInline(list, McpResourceType.Node.ToStorageName(), 100));
    }

    [Fact]
    public void IsAuthorized_TypeMismatch_ReturnsFalse()
    {
        var list = new List<McpTokenResource>
        {
            new() { Enable = true, ResourceType = McpResourceType.Node.ToStorageName(), ResourceId = 100, IsAll = true }
        };

        Assert.False(IsAuthorizedInline(list, McpResourceType.App.ToStorageName(), 100));
    }

    [Fact]
    public void IsAuthorized_EmptyList_ReturnsFalse()
    {
        Assert.False(IsAuthorizedInline(new List<McpTokenResource>(), McpResourceType.Node.ToStorageName(), 100));
    }

    [Fact]
    public void IsAll_IsAllWinsOverDirectMatch()
    {
        // IsAll 条目优先于 ResourceId 匹配
        var list = new List<McpTokenResource>
        {
            new() { Enable = true, ResourceType = McpResourceType.Node.ToStorageName(), ResourceId = 0, IsAll = true },
            new() { Enable = true, ResourceType = McpResourceType.Node.ToStorageName(), ResourceId = 100, IsAll = false }
        };

        // 任意 node ID 都应通过(因为 IsAll=true)
        Assert.True(IsAuthorizedInline(list, McpResourceType.Node.ToStorageName(), 999));
    }

    [Fact]
    public void GetAuthorizedProjectIds_IsAll_ReturnsNull()
    {
        var list = new List<McpTokenResource>
        {
            new() { Enable = true, ResourceType = McpResourceType.Project.ToStorageName(), IsAll = true }
        };

        Assert.Null(GetAuthorizedProjectIdsInline(list));
    }

    [Fact]
    public void GetAuthorizedProjectIds_SpecificIds_ReturnsArray()
    {
        var list = new List<McpTokenResource>
        {
            new() { Enable = true, ResourceType = McpResourceType.Project.ToStorageName(), ResourceId = 1, IsAll = false },
            new() { Enable = true, ResourceType = McpResourceType.Project.ToStorageName(), ResourceId = 2, IsAll = false },
            new() { Enable = true, ResourceType = McpResourceType.Project.ToStorageName(), ResourceId = 3, IsAll = false }
        };

        var ids = GetAuthorizedProjectIdsInline(list);

        Assert.NotNull(ids);
        Assert.Equal(3, ids.Length);
        Assert.Contains(1, ids);
        Assert.Contains(2, ids);
        Assert.Contains(3, ids);
    }

    [Fact]
    public void GetAuthorizedProjectIds_Empty_ReturnsEmptyArray()
    {
        var ids = GetAuthorizedProjectIdsInline(new List<McpTokenResource>());

        Assert.NotNull(ids);
        Assert.Empty(ids);
    }

    [Fact]
    public void GetAuthorizedProjectIds_FiltersNonProjectTypes()
    {
        var list = new List<McpTokenResource>
        {
            new() { Enable = true, ResourceType = McpResourceType.Node.ToStorageName(), ResourceId = 100, IsAll = false },
            new() { Enable = true, ResourceType = McpResourceType.Project.ToStorageName(), ResourceId = 1, IsAll = false }
        };

        var ids = GetAuthorizedProjectIdsInline(list);

        Assert.Single(ids);
        Assert.Contains(1, ids);
    }

    [Fact]
    public void GetAuthorizedProjectIds_FiltersDisabled()
    {
        var list = new List<McpTokenResource>
        {
            new() { Enable = false, ResourceType = McpResourceType.Project.ToStorageName(), ResourceId = 1, IsAll = false },
            new() { Enable = true, ResourceType = McpResourceType.Project.ToStorageName(), ResourceId = 2, IsAll = false }
        };

        var ids = GetAuthorizedProjectIdsInline(list);

        Assert.Single(ids);
        Assert.Contains(2, ids);
    }

    [Fact]
    public void GetAuthorizedProjectIds_Deduplicates()
    {
        var list = new List<McpTokenResource>
        {
            new() { Enable = true, ResourceType = McpResourceType.Project.ToStorageName(), ResourceId = 1, IsAll = false },
            new() { Enable = true, ResourceType = McpResourceType.Project.ToStorageName(), ResourceId = 1, IsAll = false },
            new() { Enable = true, ResourceType = McpResourceType.Project.ToStorageName(), ResourceId = 2, IsAll = false }
        };

        var ids = GetAuthorizedProjectIdsInline(list);

        Assert.Equal(2, ids.Length);
    }

    [Fact]
    public void FindById_Negative_ReturnsNull()
    {
        Assert.Null(McpTokenResource.FindById(-1));
    }
}