节点在线、应用在线、配置在线使用令牌查询
大石头 authored at 2021-12-16 19:49:30
2.88 KiB
Stardust
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.DependencyInjection;
using Stardust.Server;
using Xunit;

namespace Stardust.McpClientTests;

/// <summary>测试服务器Fixture。启动Stardust.Web进程内实例,启用MCP服务</summary>
public class McpTestServerFixture : IAsyncLifetime
{
    private TestServer? _server;
    private HttpClient? _cookieLessClient;

    /// <summary>测试服务器基础地址</summary>
    public String BaseUrl => "http://localhost/";

    /// <summary>HTTP客户端(连接到TestServer)。统一去除Cookie,避免TestServer共享CookieContainer
    /// 累积的畸形设备ID等Cookie触发 UseStardust/Cube 等前置中间件异常,干扰 /mcp 机器API测试。</summary>
    public HttpClient CreateClient()
    {
        if (_server == null) throw new InvalidOperationException("TestServer not initialized");
        if (_cookieLessClient == null)
        {
            var handler = new NoCookieHandler { InnerHandler = _server.CreateHandler() };
            _cookieLessClient = new HttpClient(handler) { BaseAddress = new Uri(BaseUrl) };
        }
        return _cookieLessClient;
    }

    /// <summary>剥离请求中的Cookie并忽略响应Set-Cookie,使每个请求互不携带会话态</summary>
    private sealed class NoCookieHandler : DelegatingHandler
    {
        protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            request.Headers.Remove("Cookie");
            var response = await base.SendAsync(request, cancellationToken);
            response.Headers.Remove("Set-Cookie");
            return response;
        }
    }

    /// <summary>获取TestServer(用于直接访问DI容器)</summary>
    public TestServer Server
    {
        get => _server ?? throw new InvalidOperationException("TestServer not initialized");
        set => _server = value;
    }

    public async Task InitializeAsync()
    {
        // 在服务器启动前启用MCP(仅修改内存值,不调用Save以避免DB未初始化)
        var set = StarServerSetting.Current;
        set.EnableMcp = true;
        set.McpActionSet = "*";

#pragma warning disable CS0618
        var builder = WebHost.CreateDefaultBuilder()
            .UseStartup<Stardust.Web.Startup>()
            .ConfigureTestServices(services =>
            {
                // 确保MCP已启用(Startup会读取StarServerSetting.Current单例)
                var setting = StarServerSetting.Current;
                setting.EnableMcp = true;
                setting.McpActionSet = "*";
            });
#pragma warning restore CS0618

        _server = new TestServer(builder);
        await Task.CompletedTask;
    }

    public Task DisposeAsync()
    {
        _server?.Dispose();
        return Task.CompletedTask;
    }
}