oficina / memoria Public

Clone
git clone https://amadan.net/oficina/memoria

Plain git — no account needed to clone.

Download

Download this file

1package memoria
2
3import (
4 "net/http"
5 "net/http/cookiejar"
6 "net/http/httptest"
7 "net/url"
8 "strings"
9 "testing"
10)
11
12// cookieBrowser carries cookies between requests the way a browser does,
13// deletions included, so a test can visit pages in an order and see what
14// each visit spent.
15type cookieBrowser struct {
16 t *testing.T
17 h http.Handler
18 jar *cookiejar.Jar
19}
20
21var cookieBase = &url.URL{Scheme: "http", Host: "example.com", Path: "/"}
22
23func newCookieBrowser(t *testing.T, h http.Handler) *cookieBrowser {
24 jar, err := cookiejar.New(nil)
25 if err != nil {
26 t.Fatal(err)
27 }
28 return &cookieBrowser{t: t, h: h, jar: jar}
29}
30
31func (b *cookieBrowser) keep(rec *httptest.ResponseRecorder) {
32 b.jar.SetCookies(cookieBase, rec.Result().Cookies())
33}
34
35func (b *cookieBrowser) visit(path string) string {
36 b.t.Helper()
37 req := httptest.NewRequest(http.MethodGet, path, nil)
38 for _, c := range b.jar.Cookies(cookieBase) {
39 req.AddCookie(c)
40 }
41 rec := httptest.NewRecorder()
42 b.h.ServeHTTP(rec, req)
43 if rec.Code != http.StatusOK {
44 b.t.Fatalf("GET %s answered %d, want 200", path, rec.Code)
45 }
46 b.keep(rec)
47 return rec.Body.String()
48}
49
50// With both notices pending, each page shows its own once and leaves the
51// other alone.
52//
53// Astra, 2026-09-29: clearing the wrong cookie passed make ci. Taking the
54// index's notice then erased a pending upload refusal and left the delete
55// notice to be said again. Both orders are run because that mutation fails
56// differently in each.
57//
58// MUTATION-TESTED 2026-09-29, reverted: the clearing cookie in
59// notice.take named string(addNotice) instead of string(n) → "/add no
60// longer shows its notice after a visit to /" and "/ showed its notice a
61// second time (/ first)".
62func TestEachPageSpendsOnlyItsOwnNotice(t *testing.T) {
63 const uploaded, deleted = "scan.png is not text", "The delete did not happen"
64 pages := map[string]string{"/": deleted, "/add": uploaded}
65 for _, order := range [][2]string{{"/", "/add"}, {"/add", "/"}} {
66 h, _ := appWithAWorkingIndex(t)
67 b := newCookieBrowser(t, h)
68 seed := httptest.NewRecorder()
69 addNotice.set(seed, "danger", uploaded)
70 indexNotice.set(seed, "danger", deleted)
71 b.keep(seed)
72
73 first, second := order[0], order[1]
74 if page := b.visit(first); !strings.Contains(page, pages[first]) {
75 t.Fatalf("%s did not show its notice with both pending", first)
76 }
77 if page := b.visit(second); !strings.Contains(page, pages[second]) {
78 t.Errorf("%s no longer shows its notice after a visit to %s", second, first)
79 }
80 for path, said := range pages {
81 if strings.Contains(b.visit(path), said) {
82 t.Errorf("%s showed its notice a second time (%s first); it is one-shot", path, first)
83 }
84 }
85 }
86}
87