package main import ( "bufio" "net/http" "testing" "time" ) // TestNestStreamSSE checks GET /api/events?nest_id= streams nest.message events // and replays history from Last-Event-ID (the EVENTS.md nest SSE contract). func TestNestStreamSSE(t *testing.T) { ts, s := newTestNestServer(t) id := newNest(t, ts, "Lab", `"Hugin"`) s.hub.OpenNest(id) if _, out := post(t, ts.URL+"/api/nests/"+id+"/messages", `{"author":"owner","text":"hello"}`); out["msg_id"] == nil { t.Fatalf("post failed: %v", out) } req, err := http.NewRequest("GET", ts.URL+"/api/events?nest_id="+id, nil) if err != nil { t.Fatal(err) } resp, err := http.DefaultClient.Do(req) if err != nil { t.Fatal(err) } defer resp.Body.Close() if ct := resp.Header.Get("Content-Type"); ct != "text/event-stream" { t.Fatalf("content type %q", ct) } // Read in a goroutine with a deadline so a stuck stream fails, not hangs. got := make(chan bool, 1) go func() { sc := bufio.NewScanner(resp.Body) for sc.Scan() { if sc.Text() == "event: nest.message" { got <- true return } } got <- false }() select { case ok := <-got: if !ok { t.Fatal("stream ended before nest.message appeared") } case <-time.After(2 * time.Second): t.Fatal("no nest.message event within 2s") } }