Skip to content
quarry Artifact [7ebe12af71]
Login

Artifact [7ebe12af71]

Artifact 7ebe12af71479fb73747deee750e5b80dca79094858d657329975af41bd697a0:


package web

import (
	"net/http/httptest"
	"path/filepath"
	"strings"
	"testing"

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

func testRegistry(t *testing.T) *ops.Registry {
	t.Helper()
	// An empty (but real) index so entity lookups answer not-found
	// rather than "no store configured".
	ix, err := index.Open(filepath.Join(t.TempDir(), "index.db"))
	if err != nil {
		t.Fatal(err)
	}
	t.Cleanup(func() { ix.Close() })
	r := ops.NewRegistry()
	if err := api.RegisterAll(r, api.Deps{Version: "9.9.9-test", Repos: map[string]*api.Repo{"test": {Index: ix}}}); err != nil {
		t.Fatal(err)
	}
	return r
}

func TestHomePageRendersThroughVersionOp(t *testing.T) {
	rec := httptest.NewRecorder()
	Handler(testRegistry(t)).ServeHTTP(rec, httptest.NewRequest("GET", "/", nil))
	if rec.Code != 200 {
		t.Fatalf("status %d", rec.Code)
	}
	body := rec.Body.String()
	if !strings.Contains(body, "quarry 9.9.9-test") {
		t.Fatalf("footer missing op-served version:\n%s", body)
	}
	if ct := rec.Header().Get("Content-Type"); !strings.HasPrefix(ct, "text/html") {
		t.Fatalf("content-type %q", ct)
	}
	if strings.Contains(body, "<script") {
		t.Fatal("no-JS baseline violated: script tag on the base page")
	}
	if !strings.Contains(body, "prefers-color-scheme") {
		t.Fatal("dark theme missing")
	}
}

func TestUnknownPathIs404(t *testing.T) {
	rec := httptest.NewRecorder()
	Handler(testRegistry(t)).ServeHTTP(rec, httptest.NewRequest("GET", "/nope", nil))
	if rec.Code != 404 {
		t.Fatalf("status %d", rec.Code)
	}
}

func TestThemed404Page(t *testing.T) {
	for _, path := range []string{"/nope", "/r/test/wiki/NoSuchPage", "/r/test/checkin/deadbeefdead", "/r/test/ticket/deadbeef"} {
		rec := httptest.NewRecorder()
		Handler(testRegistry(t)).ServeHTTP(rec, httptest.NewRequest("GET", path, nil))
		if rec.Code != 404 {
			t.Errorf("%s: status %d", path, rec.Code)
			continue
		}
		body := rec.Body.String()
		if !strings.HasPrefix(rec.Header().Get("Content-Type"), "text/html") {
			t.Errorf("%s: content-type %q — bare default 404?", path, rec.Header().Get("Content-Type"))
		}
		if !strings.Contains(body, "quarry 9.9.9-test") {
			t.Errorf("%s: 404 page missing version footer", path)
		}
		if !strings.Contains(body, `href="/"`) {
			t.Errorf("%s: 404 page has no way back into the site", path)
		}
	}
}

func TestPersistentNavOnEveryPage(t *testing.T) {
	// Ticket 010: every repo page carries that repo's nav and search
	// form; every page (fleet and 404 included) carries the site link.
	for _, path := range []string{"/r/test/timeline", "/r/test/wiki", "/r/test/ticket", "/r/test/search"} {
		rec := httptest.NewRecorder()
		Handler(testRegistry(t)).ServeHTTP(rec, httptest.NewRequest("GET", path, nil))
		body := rec.Body.String()
		for _, want := range []string{`<nav>`, `href="/r/test/timeline"`, `href="/r/test/wiki"`, `href="/r/test/ticket"`, `action="/r/test/search"`} {
			if !strings.Contains(body, want) {
				t.Errorf("%s: missing %s in header", path, want)
			}
		}
	}
	for _, path := range []string{"/", "/nope"} {
		rec := httptest.NewRecorder()
		Handler(testRegistry(t)).ServeHTTP(rec, httptest.NewRequest("GET", path, nil))
		if !strings.Contains(rec.Body.String(), `class="site" href="/"`) {
			t.Errorf("%s: missing site link", path)
		}
	}
}

func TestFleetPageListsRepos(t *testing.T) {
	rec := httptest.NewRecorder()
	Handler(testRegistry(t)).ServeHTTP(rec, httptest.NewRequest("GET", "/", nil))
	if rec.Code != 200 {
		t.Fatalf("status %d", rec.Code)
	}
	if !strings.Contains(rec.Body.String(), `href="/r/test/timeline"`) {
		t.Fatalf("fleet page missing repo link:\n%s", rec.Body.String())
	}
}

func TestTablesScrollInWrapper(t *testing.T) {
	// Ticket 120: wide tables scroll inside .tw, not the page.
	rec := httptest.NewRecorder()
	Handler(testRegistry(t)).ServeHTTP(rec, httptest.NewRequest("GET", "/r/test/timeline", nil))
	body := rec.Body.String()
	if strings.Contains(body, "<table>") && !strings.Contains(body, `<div class="tw"><table>`) {
		t.Fatalf("timeline table not wrapped:\n%s", body)
	}
}