168 lines
4.8 KiB
Go
168 lines
4.8 KiB
Go
package filemanagerrealtime
|
|
|
|
import (
|
|
"encoding/json"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestHubSubscribePublishAndClose(t *testing.T) {
|
|
hub := NewHub(4, nil)
|
|
|
|
sub, err := hub.Subscribe("01961f5c-6471-7b81-9df5-2e2e1cf7e498")
|
|
if err != nil {
|
|
t.Fatalf("subscribe: %v", err)
|
|
}
|
|
if got := hub.SubscriberCount("01961f5c-6471-7b81-9df5-2e2e1cf7e498"); got != 1 {
|
|
t.Fatalf("expected subscriber count 1, got %d", got)
|
|
}
|
|
|
|
delivered := hub.PublishToUsers([]string{"01961f5c-6471-7b81-9df5-2e2e1cf7e498"}, FileStatusEvent{
|
|
EventType: FileStatusChangedEventType,
|
|
FileUUID: "01961f5c-6471-7b81-9df5-2e2e1cf7e499",
|
|
Status: "processing",
|
|
Name: "report.pdf",
|
|
UpdatedAt: time.Now().UTC().Format(time.RFC3339),
|
|
})
|
|
if delivered != 1 {
|
|
t.Fatalf("expected one delivered event, got %d", delivered)
|
|
}
|
|
|
|
select {
|
|
case event := <-sub.Events():
|
|
if event.Status != "processing" {
|
|
t.Fatalf("expected processing status, got %q", event.Status)
|
|
}
|
|
case <-time.After(time.Second):
|
|
t.Fatalf("timed out waiting for event")
|
|
}
|
|
|
|
sub.Close()
|
|
if got := hub.SubscriberCount("01961f5c-6471-7b81-9df5-2e2e1cf7e498"); got != 0 {
|
|
t.Fatalf("expected subscriber count 0 after close, got %d", got)
|
|
}
|
|
|
|
delivered = hub.PublishToUsers([]string{"01961f5c-6471-7b81-9df5-2e2e1cf7e498"}, FileStatusEvent{
|
|
EventType: FileStatusChangedEventType,
|
|
FileUUID: "01961f5c-6471-7b81-9df5-2e2e1cf7e499",
|
|
Status: "validated",
|
|
Name: "report.pdf",
|
|
UpdatedAt: time.Now().UTC().Format(time.RFC3339),
|
|
})
|
|
if delivered != 0 {
|
|
t.Fatalf("expected no delivered event after close, got %d", delivered)
|
|
}
|
|
}
|
|
|
|
func TestFileStatusEventJSONPayload(t *testing.T) {
|
|
reason := "file bucket mismatch"
|
|
event := FileStatusEvent{
|
|
EventType: FileStatusChangedEventType,
|
|
FileUUID: "01961f5c-6471-7b81-9df5-2e2e1cf7e499",
|
|
Status: "failed",
|
|
Name: "report.pdf",
|
|
FailureReason: &reason,
|
|
UpdatedAt: "2026-04-05T07:29:34Z",
|
|
}
|
|
|
|
raw, err := json.Marshal(event)
|
|
if err != nil {
|
|
t.Fatalf("marshal: %v", err)
|
|
}
|
|
|
|
var decoded map[string]any
|
|
if err := json.Unmarshal(raw, &decoded); err != nil {
|
|
t.Fatalf("unmarshal: %v", err)
|
|
}
|
|
if decoded["event_type"] != FileStatusChangedEventType {
|
|
t.Fatalf("unexpected event_type: %#v", decoded["event_type"])
|
|
}
|
|
if decoded["status"] != "failed" {
|
|
t.Fatalf("unexpected status: %#v", decoded["status"])
|
|
}
|
|
if decoded["failure_reason"] != reason {
|
|
t.Fatalf("unexpected failure_reason: %#v", decoded["failure_reason"])
|
|
}
|
|
}
|
|
|
|
func TestHubReplaysRecentEventsOnSubscribe(t *testing.T) {
|
|
hub := NewHub(2, nil)
|
|
userID := "01961f5c-6471-7b81-9df5-2e2e1cf7e498"
|
|
|
|
// Publish without active subscribers.
|
|
if delivered := hub.PublishToUsers([]string{userID}, FileStatusEvent{
|
|
EventType: FileStatusChangedEventType,
|
|
FileUUID: "01961f5c-6471-7b81-9df5-2e2e1cf7e499",
|
|
Status: "processing",
|
|
Name: "report.pdf",
|
|
UpdatedAt: time.Now().UTC().Format(time.RFC3339),
|
|
}); delivered != 0 {
|
|
t.Fatalf("expected zero delivered before subscription, got %d", delivered)
|
|
}
|
|
|
|
sub, err := hub.Subscribe(userID)
|
|
if err != nil {
|
|
t.Fatalf("subscribe: %v", err)
|
|
}
|
|
defer sub.Close()
|
|
|
|
select {
|
|
case event := <-sub.Events():
|
|
if event.Status != "processing" {
|
|
t.Fatalf("expected replayed processing status, got %q", event.Status)
|
|
}
|
|
case <-time.After(time.Second):
|
|
t.Fatalf("timed out waiting for replayed event")
|
|
}
|
|
}
|
|
|
|
func TestHubSubscribeWithFilterSkipsUnmatchedEvents(t *testing.T) {
|
|
hub := NewHub(2, nil)
|
|
userID := "01961f5c-6471-7b81-9df5-2e2e1cf7e498"
|
|
keepFileID := "01961f5c-6471-7b81-9df5-2e2e1cf7e499"
|
|
skipFileID := "01961f5c-6471-7b81-9df5-2e2e1cf7e500"
|
|
|
|
sub, err := hub.SubscribeWithFilter(userID, func(event FileStatusEvent) bool {
|
|
return event.FileUUID == keepFileID
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("subscribe with filter: %v", err)
|
|
}
|
|
defer sub.Close()
|
|
|
|
if delivered := hub.PublishToUsers([]string{userID}, FileStatusEvent{
|
|
EventType: FileStatusChangedEventType,
|
|
FileUUID: skipFileID,
|
|
Status: "processing",
|
|
Name: "skip.pdf",
|
|
UpdatedAt: time.Now().UTC().Format(time.RFC3339),
|
|
}); delivered != 0 {
|
|
t.Fatalf("expected unmatched event to be skipped, got %d delivered", delivered)
|
|
}
|
|
|
|
if delivered := hub.PublishToUsers([]string{userID}, FileStatusEvent{
|
|
EventType: FileStatusChangedEventType,
|
|
FileUUID: keepFileID,
|
|
Status: "ready",
|
|
Name: "keep.pdf",
|
|
UpdatedAt: time.Now().UTC().Format(time.RFC3339),
|
|
}); delivered != 1 {
|
|
t.Fatalf("expected matched event to be delivered, got %d", delivered)
|
|
}
|
|
|
|
select {
|
|
case event := <-sub.Events():
|
|
if event.FileUUID != keepFileID {
|
|
t.Fatalf("expected filtered event, got %q", event.FileUUID)
|
|
}
|
|
case <-time.After(time.Second):
|
|
t.Fatalf("timed out waiting for filtered event")
|
|
}
|
|
|
|
select {
|
|
case event := <-sub.Events():
|
|
t.Fatalf("unexpected extra event delivered: %#v", event)
|
|
case <-time.After(50 * time.Millisecond):
|
|
}
|
|
}
|