Skip to content
quarry Artifact [3a69e0c67f]
Login

Artifact [3a69e0c67f]

Artifact 3a69e0c67f339106573efa2ec199a5df58c2fe474999477a2e5b4dbbd0b7ed07:


package web

import (
	"net/http"
	"net/http/httptest"
	"os"
	"strings"
	"testing"

	"craftdesign.group/quarry/internal/api"
	"craftdesign.group/quarry/internal/ops"
)

// The inbox page is live the way the badge is: it opens the attention
// stream itself, asking for the list, and the live region it patches
// carries an id the stream can address.
func TestInboxPageOpensTheStreamForItsList(t *testing.T) {
	r := ops.NewRegistry()
	if err := api.RegisterAll(r, api.Deps{Version: "v", Repos: api.NewRepos(map[string]*api.Repo{})}); err != nil {
		t.Fatal(err)
	}
	srv := httptest.NewServer(HandlerWith(r, nil, nil, []Option{WithSessions(fakeSessions{user: "dan"})}))
	t.Cleanup(srv.Close)
	req, _ := http.NewRequest("GET", srv.URL+"/inbox?f=mentions", nil)
	req.AddCookie(&http.Cookie{Name: sessionCookie, Value: "good"})
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		t.Fatal(err)
	}
	page := body(res)
	if !strings.Contains(page, `id="inbox-live"`) {
		t.Error("the inbox has no live region to patch")
	}
	if !strings.Contains(page, `@get('/me.sse?inbox=1&f=mentions')`) {
		t.Errorf("the inbox does not open the stream for its list")
	}
	if strings.Count(page, "/me.sse") != 1 {
		t.Errorf("the page opens the attention stream %d times, want once", strings.Count(page, "/me.sse"))
	}
}

// On the stream, an event re-renders the list and patches it; an event
// that leaves the list as it was sends nothing.
func TestAttentionStreamPatchesTheInboxList(t *testing.T) {
	rec := httptest.NewRecorder()
	frag := `<div id="inbox-live">one</div>`
	s := &attentionSSE{w: rec, fl: rec, ctx: t.Context(), r: ops.NewRegistry(), inbox: func() string { return frag }}
	_ = s.Emit(1, attentionEvent{})
	out := rec.Body.String()
	if !strings.Contains(out, "data: elements "+frag) {
		t.Fatalf("no inbox patch on the stream:\n%s", out)
	}
	_ = s.Emit(2, attentionEvent{})
	if n := strings.Count(rec.Body.String(), "data: elements "+frag); n != 1 {
		t.Fatalf("an unchanged list was patched %d times", n)
	}
	frag = `<div id="inbox-live">two</div>`
	_ = s.Emit(3, attentionEvent{})
	if !strings.Contains(rec.Body.String(), "data: elements "+frag) {
		t.Fatal("a changed list was not patched")
	}
	quiet := &attentionSSE{w: httptest.NewRecorder(), fl: httptest.NewRecorder(), ctx: t.Context(), r: ops.NewRegistry()}
	_ = quiet.Emit(1, attentionEvent{})
	if strings.Contains(quiet.w.(*httptest.ResponseRecorder).Body.String(), "inbox-live") {
		t.Fatal("a stream opened without the inbox patched an inbox")
	}
}

// A page restored from the back-forward cache is the page as it was
// left, with its streams closed: a live page reloads on restore.
func TestLivePagesReloadFromTheBackCache(t *testing.T) {
	js, err := os.ReadFile("assets/onerror.js")
	if err != nil {
		t.Fatal(err)
	}
	src := string(js)
	for _, want := range []string{`"pageshow"`, "ev.persisted", "location.reload()", `querySelector("[data-init]")`} {
		if !strings.Contains(src, want) {
			t.Errorf("onerror.js lacks %s", want)
		}
	}
}