From 014eafa5bc951ce8f0e69efb07dda9b5e1551dfc Mon Sep 17 00:00:00 2001 From: Rory& Date: Fri, 4 Sep 2026 13:37:18 +0200 Subject: [PATCH] Add failing tests for custom presence --- .../Spacebar.Tests/Tests/PresenceTests.cs | 85 +++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 extra/admin-api/Tests/Spacebar.Tests/Tests/PresenceTests.cs diff --git a/extra/admin-api/Tests/Spacebar.Tests/Tests/PresenceTests.cs b/extra/admin-api/Tests/Spacebar.Tests/Tests/PresenceTests.cs new file mode 100644 index 000000000..603bae7b8 --- /dev/null +++ b/extra/admin-api/Tests/Spacebar.Tests/Tests/PresenceTests.cs @@ -0,0 +1,85 @@ +using System.Diagnostics; +using System.Net.Http.Json; +using System.Net.WebSockets; +using System.Text.Json; +using System.Text.Json.Nodes; +using ArcaneLibs.Extensions; +using Spacebar.Models.Gateway; +using Spacebar.Models.Generic; +using Spacebar.Sdk.Core; +using Spacebar.Tests.Abstractions; +using Spacebar.Tests.Extensions; +using Spacebar.Tests.Fixtures; +using Xunit.Internal; +using Xunit.Microsoft.DependencyInjection.Abstracts; + +namespace Spacebar.Tests.Tests; + +public class PresenceTests(ITestOutputHelper testOutputHelper, TestFixture fixture) : TestBed(testOutputHelper, fixture), IAsyncLifetime +{ + private readonly Config _config = fixture.GetRequiredService(testOutputHelper); + private readonly UserAbstraction _userAbstraction = fixture.GetRequiredService(testOutputHelper); + + private static AuthenticatedSpacebarClient Client { get; set; } = null!; + + public async ValueTask InitializeAsync() + { + testOutputHelper.WriteLine("Running InitializeAsync"); + // All these tests can share a single client + Client = await _userAbstraction.GetSharedUser(); + } + + [Fact] + public async Task CanSendCustomPresence() + { + Client.Gateway.OnceGatewayMessage.Add(async payload => + { + if (payload is { Opcode: GatewayOpcode.S2CDispatch, DispatchEventType: "READY" }) + { + _testOutputHelper.WriteLine("Sending presence..."); + + var presencePayload = new JsonObject() + { + { "status", "online" }, + { "since", 0 }, + { "afk", false }, + { "activities", new JsonArray() { + new JsonObject() { + { "name", "Custom Status" }, + { "type", 4 }, + { "state", "meowmeow custom status meow meow" }, + { "timestamps", new JsonObject() { + { "end", 1788544741128 } + } + }, + { "emoji", null }, + { "metadata", new JsonObject() } + } + } + } + }; + + await Client.Gateway.RawClientWebSocket.SendAsync(JsonSerializer.SerializeToUtf8Bytes(new GatewayPayload() + { + Opcode = GatewayOpcode.C2SPresenceUpdate, + EventData = presencePayload.ToJsonNode().AsObject() + }), WebSocketMessageType.Text, WebSocketMessageFlags.EndOfMessage, CancellationToken.None); + _testOutputHelper.WriteLine("Sent presence payload..."); + return true; + } + + _testOutputHelper.WriteLine("Received message: {0}", payload.ToJson(indent: false)); + return false; + }); + // Client.Gateway.TraceGatewayMessages = true; + await Client.Gateway.Connect(); + try + { + await Client.Gateway.Start(); + } + catch (Exception e) + { + Assert.True(Client.Gateway.RawClientWebSocket.State == WebSocketState.Open, $"Client.Gateway.RawClientWebSocket.State is {Client.Gateway.RawClientWebSocket.State}: {Client.Gateway.RawClientWebSocket.CloseStatus}/{Client.Gateway.RawClientWebSocket.CloseStatusDescription}"); + } + } +} \ No newline at end of file