Skip to content

Commit a0afb5e

Browse files
committed
feat: sse tests
1 parent 696d4c1 commit a0afb5e

File tree

2 files changed

+34
-39
lines changed

2 files changed

+34
-39
lines changed

tests/Server.cs

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
using Sisk.Core.Entity; // Added for MultipartFormCollection and MultipartObject
22
using Sisk.Core.Http;
33
using Sisk.Core.Http.Hosting;
4-
using Sisk.Core.Routing;
54
using Sisk.Core.Http.Streams; // Added for HttpRequestEventSource
6-
using System.Threading; // Added for Thread.Sleep
7-
using System.Threading.Tasks; // Added for async Task and Task.Delay
5+
using Sisk.Core.Routing;
86
using System.Collections.Generic; // Added for List and Dictionary
97
using System.Linq;
108
using System.Net.Http.Json;
119
using System.Text;
10+
using System.Threading; // Added for Thread.Sleep
11+
using System.Threading.Tasks; // Added for async Task and Task.Delay
1212

1313
namespace tests;
1414

@@ -23,6 +23,7 @@ public sealed class Server
2323
public static void AssemblyInit(TestContext testContext)
2424
{
2525
Instance = HttpServer.CreateBuilder()
26+
.UseCors(new CrossOriginResourceSharingHeaders(allowOrigin: "*", allowMethods: ["GET", "POST", "PUT"]))
2627
.UseRouter(router =>
2728
{
2829
router.MapGet("/tests/plaintext", delegate (HttpRequest request)
@@ -599,44 +600,42 @@ public static void AssemblyInit(TestContext testContext)
599600
// SSE Routes
600601
router.SetRoute(RouteMethod.Get, "/tests/sse/sync", (req) =>
601602
{
602-
var eventSource = req.OpenEventSource();
603+
var eventSource = req.GetEventSource();
603604
eventSource.AppendHeader("X-Test-SSE", "sync");
604605
eventSource.Send("message 1 part 1");
605606
eventSource.Send("message 1 part 2");
606-
eventSource.Send("message 2 part 1", eventName: "customSync");
607-
eventSource.Send("message 2 part 2", eventName: "customSync");
607+
eventSource.Send("message 2 part 1", fieldName: "customSync");
608+
eventSource.Send("message 2 part 2", fieldName: "customSync");
608609
return eventSource.Close();
609610
});
610611

611612
router.SetRoute(RouteMethod.Get, "/tests/sse/async", async (HttpRequest req) =>
612613
{
613-
var eventSource = req.OpenEventSource();
614+
var eventSource = await req.GetEventSourceAsync();
614615
eventSource.AppendHeader("X-Test-SSE", "async");
615616
await eventSource.SendAsync("async message 1");
616617
await Task.Delay(50);
617-
await eventSource.SendAsync("async message 2", eventName: "customAsync");
618+
await eventSource.SendAsync("async message 2", fieldName: "customAsync");
618619
await Task.Delay(50);
619620
await eventSource.SendAsync("async message 3");
620621
return eventSource.Close();
621622
});
622623

623-
var sseCorsRoute = router.SetRoute(RouteMethod.Get, "/tests/sse/cors", (req) =>
624+
router.SetRoute(RouteMethod.Get, "/tests/sse/cors", (req) =>
624625
{
625-
var eventSource = req.OpenEventSource();
626-
// eventSource.AppendHeader("Access-Control-Allow-Origin", "*"); // This will be handled by UseCors = true
626+
var eventSource = req.GetEventSource();
627627
eventSource.AppendHeader("X-Test-SSE", "cors");
628628
eventSource.Send("cors message 1");
629629
return eventSource.Close();
630630
});
631-
sseCorsRoute.UseCors = true;
632631

633632
router.SetRoute(RouteMethod.Get, "/tests/sse/empty", (req) =>
634633
{
635-
var eventSource = req.OpenEventSource();
634+
var eventSource = req.GetEventSource();
636635
eventSource.Send(""); // Default event name "message", empty data
637636
eventSource.Send(null); // Default event name "message", null data (becomes empty)
638-
eventSource.Send("", eventName: "customEmpty"); // Custom event name, empty data
639-
eventSource.Send(null, eventName: "customNull"); // Custom event name, null data (becomes empty)
637+
eventSource.Send("", fieldName: "customEmpty"); // Custom event name, empty data
638+
eventSource.Send(null, fieldName: "customNull"); // Custom event name, null data (becomes empty)
640639
return eventSource.Close();
641640
});
642641
})

tests/Tests/HttpEventSourceTests.cs

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ public class SseEvent
1717
public string EventName { get; set; } = "message"; // Default SSE event name
1818
public string Data { get; set; } = "";
1919

20-
public override string ToString() => $"event: {EventName}\ndata: {Data}\n\n";
20+
public override string ToString() => $"(Event=\"{EventName}\" Data=\"{Data}\")";
21+
2122
public override bool Equals(object? obj)
2223
{
2324
return obj is SseEvent other &&
@@ -60,15 +61,19 @@ private async Task<List<SseEvent>> ReadSseEventsAsync(HttpResponseMessage respon
6061
currentEvent = new SseEvent(); // Reset for next event
6162
dataBuffer.Clear();
6263
}
63-
else if (line.StartsWith("event:"))
64+
else if (line.Contains(':'))
6465
{
65-
currentEvent.EventName = line.Substring("event:".Length).Trim();
66+
var parts = line.Split(':', StringSplitOptions.TrimEntries);
67+
events.Add(new SseEvent()
68+
{
69+
Data = parts[1],
70+
EventName = parts[0]
71+
});
6672
}
67-
else if (line.StartsWith("data:"))
73+
else
6874
{
69-
dataBuffer.AppendLine(line.Substring("data:".Length).TrimStart(' '));
75+
Assert.Fail("invalid SSE line");
7076
}
71-
// Ignore id, retry, and comment lines for these tests
7277
}
7378
// In case the stream ends without a final blank line but there's data buffered
7479
if (dataBuffer.Length > 0)
@@ -92,21 +97,12 @@ public async Task TestSyncSseFeatures()
9297
Assert.AreEqual("sync", headerValues?.FirstOrDefault(), "X-Test-SSE header value incorrect.");
9398

9499
var receivedEvents = await ReadSseEventsAsync(response);
95-
96-
// Server sends:
97-
// eventSource.Send("message 1 part 1");
98-
// eventSource.Send("message 1 part 2");
99-
// eventSource.Send("message 2 part 1", eventName: "customSync");
100-
// eventSource.Send("message 2 part 2", eventName: "customSync");
101-
// ReadSseEventsAsync currently combines data lines for the same event.
102-
// The server code sends "message 1 part 1" and "message 1 part 2" as separate events by default
103-
// because .Send() is called multiple times.
104-
// Let's adjust expected based on server logic: each Send is one event.
105-
106100
var expectedEvents = new List<SseEvent>
107101
{
108-
new SseEvent { EventName = "message", Data = "message 1 part 1" },
109-
new SseEvent { EventName = "customSync", Data = "message 2 part 1" }
102+
new SseEvent { EventName = "data", Data = "message 1 part 1" },
103+
new SseEvent { EventName = "data", Data = "message 1 part 2" },
104+
new SseEvent { EventName = "customSync", Data = "message 2 part 1" },
105+
new SseEvent { EventName = "customSync", Data = "message 2 part 2" }
110106
};
111107

112108
CollectionAssert.AreEqual(expectedEvents, receivedEvents, "The received SSE events do not match the expected events.");
@@ -131,9 +127,9 @@ public async Task TestAsyncSseFeatures()
131127

132128
var expectedEvents = new List<SseEvent>
133129
{
134-
new SseEvent { EventName = "message", Data = "async message 1" },
130+
new SseEvent { EventName = "data", Data = "async message 1" },
135131
new SseEvent { EventName = "customAsync", Data = "async message 2" },
136-
new SseEvent { EventName = "message", Data = "async message 3" }
132+
new SseEvent { EventName = "data", Data = "async message 3" }
137133
};
138134

139135
CollectionAssert.AreEqual(expectedEvents, receivedEvents, "The received asynchronous SSE events do not match the expected events.");
@@ -165,7 +161,7 @@ public async Task TestSseWithCorsHeaders()
165161

166162
var expectedEvents = new List<SseEvent>
167163
{
168-
new SseEvent { EventName = "message", Data = "cors message 1" }
164+
new SseEvent { EventName = "data", Data = "cors message 1" }
169165
};
170166

171167
CollectionAssert.AreEqual(expectedEvents, receivedEvents, "The received SSE events for CORS test do not match the expected events.");
@@ -187,8 +183,8 @@ public async Task TestSseEmptyNullDataEvents()
187183

188184
var expectedEvents = new List<SseEvent>
189185
{
190-
new SseEvent { EventName = "message", Data = "" },
191-
new SseEvent { EventName = "message", Data = "" },
186+
new SseEvent { EventName = "data", Data = "" },
187+
new SseEvent { EventName = "data", Data = "" },
192188
new SseEvent { EventName = "customEmpty", Data = "" },
193189
new SseEvent { EventName = "customNull", Data = "" }
194190
};

0 commit comments

Comments
 (0)