internal/httpd/anchors_test.go

v1.37.0
gitbay/internal/httpd/anchors_test.go history · blame · raw

83 lines · 3149 bytes

 1package httpd
 2
 3import (
 4	"net/http"
 5	"net/http/httptest"
 6	"strings"
 7	"testing"
 8
 9	"gitbay.org/gitbay/internal/config"
10	"gitbay.org/gitbay/internal/control"
11	"gitbay.org/gitbay/internal/store"
12	"gitbay.org/gitbay/internal/web"
13)
14
15// Markdown headings carry ids, so a README section can be deep-linked
16// the way org headings already could (#132).
17func TestMarkdownHeadingAnchors(t *testing.T) {
18	out := string(renderReadme("README.md", []byte("# Getting started\n\n## Two words\n\n- [ ] a task\n")))
19	for _, want := range []string{`id="getting-started"`, `id="two-words"`, `type="checkbox"`} {
20		if !strings.Contains(out, want) {
21			t.Errorf("rendered markdown lacks %s:\n%s", want, out)
22		}
23	}
24}
25
26// The stylesheet carries an ETag and a cache lifetime; a revalidation
27// with the same tag is a 304 with no body (#132).
28func TestStylesheetRevalidates(t *testing.T) {
29	s := New(config.Default(), nil, nil)
30	first := httptest.NewRecorder()
31	s.stylesheet(first, httptest.NewRequest("GET", "/static/style.css", nil))
32	tag := first.Header().Get("ETag")
33	if first.Code != 200 || tag == "" || first.Body.Len() == 0 || !strings.Contains(first.Header().Get("Cache-Control"), "max-age") {
34		t.Fatalf("first fetch: %d etag=%q cc=%q bytes=%d", first.Code, tag, first.Header().Get("Cache-Control"), first.Body.Len())
35	}
36	req := httptest.NewRequest("GET", "/static/style.css", nil)
37	req.Header.Set("If-None-Match", tag)
38	second := httptest.NewRecorder()
39	s.stylesheet(second, req)
40	if second.Code != http.StatusNotModified || second.Body.Len() != 0 {
41		t.Fatalf("revalidation: %d with %d bytes", second.Code, second.Body.Len())
42	}
43}
44
45// The layout stamps the served bytes' hash on the stylesheet URL, so a
46// deploy changes that URL and a browser cannot answer it from a copy of
47// the old sheet. A URL carrying the hash names bytes that cannot change
48// and is served without revalidation; the bare URL keeps its lifetime
49// (#239).
50func TestStylesheetURLCarriesTheBuildHash(t *testing.T) {
51	var sb strings.Builder
52	var base basePage
53	base.Viewer = "alice"
54	err := web.Render(&sb, "dashboard.html", struct {
55		basePage
56		Tab      string
57		Pins     []pinnedRow
58		Reviews  []store.DashboardItem
59		Assigned []store.DashboardItem
60		MRs      []store.DashboardItem
61		Issues   []store.DashboardItem
62		Feed     []control.FeedLine
63	}{base, "dashboard", nil, nil, nil, nil, nil, nil})
64	if err != nil {
65		t.Fatal(err)
66	}
67	want := `href="/static/style.css?v=` + stylesheetHash + `"`
68	if !strings.Contains(sb.String(), want) {
69		t.Errorf("the page does not link %s", want)
70	}
71
72	s := New(config.Default(), nil, nil)
73	versioned := httptest.NewRecorder()
74	s.stylesheet(versioned, httptest.NewRequest("GET", "/static/style.css?v="+stylesheetHash, nil))
75	if cc := versioned.Header().Get("Cache-Control"); !strings.Contains(cc, "immutable") {
76		t.Errorf("versioned URL: Cache-Control = %q, want immutable", cc)
77	}
78	bare := httptest.NewRecorder()
79	s.stylesheet(bare, httptest.NewRequest("GET", "/static/style.css", nil))
80	if cc := bare.Header().Get("Cache-Control"); !strings.Contains(cc, "must-revalidate") {
81		t.Errorf("bare URL: Cache-Control = %q, want must-revalidate", cc)
82	}
83}