解决MySql布尔型新旧版本兼容问题,采用枚举来表示布尔型的数据表。由正向工程赋值
大石头 authored at 2018-05-15 21:21:05
4.57 KiB
X
using NewLife;
using NewLife.Data;
using NewLife.Messaging;
using Xunit;

namespace XUnitTest.Messaging;

public class EventHubIntegrationTests
{
    private sealed class TestEvent
    {
        public String Message { get; set; } = String.Empty;
    }

    private sealed class TestEventHandler : IEventHandler<TestEvent>
    {
        public String HandledMessage { get; private set; } = String.Empty;

        public Task HandleAsync(TestEvent @event, IEventContext? context, CancellationToken cancellationToken)
        {
            HandledMessage = @event.Message;
            return Task.CompletedTask;
        }
    }

    [Fact(DisplayName = "多客户端订阅同一主题_发布后所有客户端收到_发布者除外")]
    public async Task MultiClient_Subscribe_Publish_SenderExcluded()
    {
        var hub = new EventHub<TestEvent>();

        // c1 订阅
        var h1 = new TestEventHandler();
        var c1Ctx = new EventContext();
        c1Ctx["Handler"] = h1;
        await hub.OnReceiveAsync("event#chat#c1#subscribe", c1Ctx);

        // c2 订阅
        var h2 = new TestEventHandler();
        var c2Ctx = new EventContext();
        c2Ctx["Handler"] = h2;
        await hub.OnReceiveAsync("event#chat#c2#subscribe", c2Ctx);

        // sender 也订阅(发布时不应收到自己的消息)
        var hSender = new TestEventHandler();
        var senderSubCtx = new EventContext();
        senderSubCtx["Handler"] = hSender;
        await hub.OnReceiveAsync("event#chat#sender#subscribe", senderSubCtx);

        // 发布时传入上下文以触发发送方排除逻辑
        var pubCtx = new EventContext();
        var rs = await hub.OnReceiveAsync("event#chat#sender#{\"Message\":\"hello\"}", pubCtx);

        Assert.Equal("hello", h1.HandledMessage);
        Assert.Equal("hello", h2.HandledMessage);
        Assert.Equal(String.Empty, hSender.HandledMessage);
        Assert.Equal(2, rs);
    }

    [Fact(DisplayName = "二进制报文流 subscribe 后 publish IPacket 端到端")]
    public async Task PacketFlow_SubscribeThenPublish_EndToEnd()
    {
        var hub = new EventHub<TestEvent>();
        var handler = new TestEventHandler();

        // 通过二进制报文订阅
        var subCtx = new EventContext();
        subCtx["Handler"] = handler;
        await hub.OnReceiveAsync(new ArrayPacket("event#device#c1#subscribe".GetBytes()), subCtx);

        // 通过二进制报文发布
        var pubPacket = new ArrayPacket("event#device#sender#{\"Message\":\"ping\"}".GetBytes());
        var rs = await hub.OnReceiveAsync(pubPacket, null);

        Assert.Equal(1, rs);
        Assert.Equal("ping", handler.HandledMessage);
    }

    [Fact(DisplayName = "Unsubscribe 后总线自动清理_再 publish 返回 0")]
    public async Task Unsubscribe_AutoCleansUpBus_ThenPublishReturnsZero()
    {
        var hub = new EventHub<TestEvent>();
        var handler = new TestEventHandler();

        // 订阅
        var subCtx = new EventContext();
        subCtx["Handler"] = handler;
        await hub.OnReceiveAsync("event#device#c1#subscribe", subCtx);
        Assert.True(hub.TryGetBus("device", out _));

        // 取消订阅 — 总线应被清理
        await hub.OnReceiveAsync("event#device#c1#unsubscribe", null);
        Assert.False(hub.TryGetBus("device", out _));

        // 此时发布应返回 0
        var rs = await hub.OnReceiveAsync("event#device#sender#{\"Message\":\"lost\"}", null);
        Assert.Equal(0, rs);
    }

    [Fact(DisplayName = "并发主题互不干扰")]
    public async Task Topics_DoNotInterfere()
    {
        var hub = new EventHub<TestEvent>();
        var handlerA = new TestEventHandler();
        var handlerB = new TestEventHandler();

        hub.GetEventBus("topicA").Subscribe(handlerA);
        hub.GetEventBus("topicB").Subscribe(handlerB);

        await hub.OnReceiveAsync("event#topicA#sender#{\"Message\":\"msgA\"}", null);

        Assert.Equal("msgA", handlerA.HandledMessage);
        Assert.Equal(String.Empty, handlerB.HandledMessage);
    }

    [Fact(DisplayName = "IoT指令确认场景_ReceiveAsync在发布前已等待")]
    public async Task IoT_CommandConfirmation_PublishAfterReceiveStarted()
    {
        var hub = new EventHub<TestEvent>();

        var receiveTask = hub.ReceiveAsync("device-001", TimeSpan.FromSeconds(5));

        // 模拟设备异步应答
        _ = Task.Run(async () =>
        {
            await Task.Delay(50);
            await hub.PublishAsync("device-001", new TestEvent { Message = "ACK" });
        });

        var result = await receiveTask;
        Assert.Equal("ACK", result.Message);
    }
}