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 "encoding/json"
5 "net/http"
6 "net/http/httptest"
7 "os"
8 "path/filepath"
9 "regexp"
10 "strings"
11 "testing"
12)
13
14// The Open source page is PUBLIC since the shared chrome (spec §8.4: the
15// sign-in page links to it, "reachable while signed out"). It says nothing
16// about the team, and it still shows a signed-in viewer their own chrome:
17// the account menu with its one Sign out, and Sources.
18//
19// Mutation-checked 2026-09-11: removing either route fails this test.
20func TestCreditsArePublicAndContainDependencyNotices(t *testing.T) {
21 fixture := newHomeRouterFixture(t)
22 app := fixture.handler
23 anonymous := fixture.do(http.MethodGet, "/help/open-source", "")
24 if anonymous.Code != http.StatusOK || !strings.Contains(anonymous.Body.String(), "estilo-credits") {
25 t.Fatal("signed-out credits unavailable", anonymous.Code)
26 }
27 for _, private := range []string{"estilo-account", "Sign out", "Sources", `rst-refresh="passages"`, "leaves this instance"} {
28 if strings.Contains(anonymous.Body.String(), private) {
29 t.Fatal("signed-out credits carry signed-in chrome", private)
30 }
31 }
32 if !strings.Contains(anonymous.Body.String(), "estilo-bar-signin") {
33 t.Fatal("signed-out credits have no Sign in corner")
34 }
35 fixture.local(t)
36 response := fixture.do(http.MethodGet, "/help/open-source", "")
37 if response.Code != http.StatusOK || response.Header().Get("Location") != "" || len(response.Result().Cookies()) != 0 {
38 t.Fatal("signed-in credits unavailable", response.Code)
39 }
40 for _, wanted := range []string{"estilo-account", "Sources", "No notice file is included in this release."} {
41 if !strings.Contains(response.Body.String(), wanted) {
42 t.Fatal("credits lost signed-in shell or missing notice label", wanted)
43 }
44 }
45 if n := strings.Count(response.Body.String(), ">Sign out<"); n != 1 {
46 t.Fatalf("credits carry %d Sign outs, want exactly one", n)
47 }
48 // strict-origin, not no-referrer (spec §9.5): with Home a Sign out
49 // from this page is chained to id.*, which admits it by Referer.
50 if response.Header().Get("Cache-Control") != "no-store" || response.Header().Get("Referrer-Policy") != "strict-origin" {
51 t.Fatal("credits headers", response.Header().Get("Cache-Control"), response.Header().Get("Referrer-Policy"))
52 }
53 for _, wanted := range []string{"estilo-credits", "Open source", "Lucide and Feather", "gorm.io/gorm", "gormlite/LICENSE", "/static/credits.css"} {
54 if !strings.Contains(response.Body.String(), wanted) {
55 t.Fatal("missing credit", wanted)
56 }
57 }
58 style := httptest.NewRecorder()
59 app.ServeHTTP(style, httptest.NewRequest(http.MethodGet, homeTestOrigin+"/static/credits.css", nil))
60 if style.Code != http.StatusOK || !strings.HasPrefix(style.Header().Get("Content-Type"), "text/css") || !strings.Contains(style.Body.String(), "[estilo-credits]") {
61 t.Fatal("shared credit styles not served")
62 }
63 if output := os.Getenv("MEMORIA_CREDITS_EVIDENCE_DIR"); output != "" {
64 if err := os.MkdirAll(output, 0700); err != nil {
65 t.Fatal(err)
66 }
67 if err := os.WriteFile(filepath.Join(output, "page.html"), response.Body.Bytes(), 0600); err != nil {
68 t.Fatal(err)
69 }
70 for _, match := range regexp.MustCompile(`(?:href|src)="(/static/[^" ]+)"`).FindAllStringSubmatch(response.Body.String(), -1) {
71 asset := httptest.NewRecorder()
72 app.ServeHTTP(asset, httptest.NewRequest(http.MethodGet, homeTestOrigin+match[1], nil))
73 if asset.Code != http.StatusOK {
74 t.Fatal("credits fixture asset unavailable", match[1])
75 }
76 if err := os.WriteFile(filepath.Join(output, filepath.Base(match[1])), asset.Body.Bytes(), 0600); err != nil {
77 t.Fatal(err)
78 }
79 }
80 }
81 var inventory creditInventory
82 if err := json.Unmarshal(creditNotices, &inventory); err != nil {
83 t.Fatal(err)
84 }
85 if len(inventory.MissingNotices) != 1 || inventory.MissingNotices[0] != "github.com/keymaildev/signin" {
86 t.Fatal("new missing notice requires review")
87 }
88}
89
90// Mutation-checked 2026-09-11: a served undefined token fails this gate.
91func TestCreditStylesUseServedTokens(t *testing.T) {
92 definitions := map[string]bool{}
93 for _, path := range []string{"static/tokens.css", "static/theme.css"} {
94 raw, err := appFS.ReadFile(path)
95 if err != nil {
96 t.Fatal(err)
97 }
98 for _, m := range regexp.MustCompile(`(--rst-[a-z0-9-]+)\s*:`).FindAllSubmatch(raw, -1) {
99 definitions[string(m[1])] = true
100 }
101 }
102 response := httptest.NewRecorder()
103 serveCreditsCSS(response, httptest.NewRequest(http.MethodGet, "/static/credits.css", nil))
104 if response.Header().Get("Cache-Control") != "no-cache" {
105 t.Fatal("shared CSS can be stale")
106 }
107 references := regexp.MustCompile(`var\(\s*(--rst-[a-z0-9-]+)`).FindAllSubmatch(response.Body.Bytes(), -1)
108 if len(references) == 0 {
109 t.Fatal("credit token references disappeared")
110 }
111 for _, m := range references {
112 if !definitions[string(m[1])] {
113 t.Fatal("undefined served credit token", string(m[1]))
114 }
115 }
116}
117