memos/server/router/api/v1/sse_hub_test.go

71 lines
1.7 KiB
Go

package v1
import (
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestSSEHub_SubscribeUnsubscribe(t *testing.T) {
hub := NewSSEHub()
client := hub.Subscribe()
require.NotNil(t, client)
require.NotNil(t, client.events)
// Unsubscribe removes the client and closes the channel.
hub.Unsubscribe(client)
// Channel should be closed.
_, ok := <-client.events
assert.False(t, ok, "channel should be closed after Unsubscribe")
}
func TestSSEHub_Broadcast(t *testing.T) {
hub := NewSSEHub()
client := hub.Subscribe()
defer hub.Unsubscribe(client)
event := &SSEEvent{Type: SSEEventMemoCreated, Name: "memos/123"}
hub.Broadcast(event)
select {
case data := <-client.events:
assert.Contains(t, string(data), `"type":"memo.created"`)
assert.Contains(t, string(data), `"name":"memos/123"`)
case <-time.After(time.Second):
t.Fatal("expected to receive event within 1s")
}
}
func TestSSEHub_BroadcastMultipleClients(t *testing.T) {
hub := NewSSEHub()
c1 := hub.Subscribe()
defer hub.Unsubscribe(c1)
c2 := hub.Subscribe()
defer hub.Unsubscribe(c2)
event := &SSEEvent{Type: SSEEventMemoDeleted, Name: "memos/456"}
hub.Broadcast(event)
for _, ch := range []chan []byte{c1.events, c2.events} {
select {
case data := <-ch:
assert.Contains(t, string(data), "memo.deleted")
assert.Contains(t, string(data), "memos/456")
case <-time.After(time.Second):
t.Fatal("expected to receive event within 1s")
}
}
}
func TestSSEEvent_JSON(t *testing.T) {
e := &SSEEvent{Type: SSEEventMemoUpdated, Name: "memos/789"}
data := e.JSON()
require.NotEmpty(t, data)
assert.Contains(t, string(data), `"type":"memo.updated"`)
assert.Contains(t, string(data), `"name":"memos/789"`)
}