Skip to content
quarry Artifact [808fab63be]
Login

Artifact [808fab63be]

Artifact 808fab63be443b8177c277cabf1c066398fdb113d6ca6b3b13ff0f1db8d21551:


package web

import (
	"strings"
	"testing"
)

// With no uploaded image — the ordinary case, and the only case on a
// forge that has bound no storage — everything keeps the identicon
// derived from its name.
func TestWithoutAnUploadEverythingKeepsItsIdenticon(t *testing.T) {
	old := avatarTag
	t.Cleanup(func() { avatarTag = old })

	avatarTag = nil
	if got := repoIcon("quarry"); got != identicon("quarry") {
		t.Errorf("FAIL: no lookup at all did not fall back")
	}
	avatarTag = func(kind, name string) (string, bool) { return "", false }
	if got := repoIcon("quarry"); got != identicon("quarry") {
		t.Errorf("FAIL: a lookup that says no did not fall back")
	}
	// An empty validator is not an image either: it would produce a
	// URL that can never be invalidated.
	avatarTag = func(kind, name string) (string, bool) { return "", true }
	if got := repoIcon("quarry"); got != identicon("quarry") {
		t.Errorf("FAIL: an empty validator was drawn as an image")
	}
}

// The validator is in the URL, not only in a header. The image is
// served immutable, so a new upload has to arrive at a NEW address or
// a reader who already has the old one never asks again.
func TestAnUploadedMarkCarriesItsValidatorInTheURL(t *testing.T) {
	old := avatarTag
	t.Cleanup(func() { avatarTag = old })
	avatarTag = func(kind, name string) (string, bool) {
		return strings.Repeat("a", 64), true
	}
	got := string(repoIcon("quarry"))
	for _, want := range []string{
		`<img`, `src="/r/quarry/avatar?v=aaaaaaaaaaaa"`, `alt=""`, `loading="lazy"`,
	} {
		if !strings.Contains(got, want) {
			t.Errorf("FAIL: the mark is missing %q: %s", want, got)
		}
	}
	// A second upload is a second address.
	avatarTag = func(kind, name string) (string, bool) {
		return strings.Repeat("b", 64), true
	}
	if second := string(repoIcon("quarry")); second == got {
		t.Errorf("FAIL: a new image reuses the old address")
	}
}

// A team and a repository of one name are two marks at two addresses:
// the kind is half the key, and the template says which it means.
func TestATeamAndARepositoryDrawFromTheirOwnKind(t *testing.T) {
	old := avatarTag
	t.Cleanup(func() { avatarTag = old })
	avatarTag = func(kind, name string) (string, bool) {
		return kind + "-" + strings.Repeat("f", 20), true
	}
	repo, team := string(repoIcon("quarry")), string(teamIcon("quarry"))
	if !strings.Contains(repo, `src="/r/quarry/avatar`) {
		t.Errorf("FAIL: the repository's mark points at %s", repo)
	}
	if !strings.Contains(team, `src="/t/quarry/avatar`) {
		t.Errorf("FAIL: the team's mark points at %s", team)
	}
	if repo == team {
		t.Errorf("FAIL: one name gave one mark for two kinds")
	}
}

// With no storage bound — which is every forge until an operator binds
// one — the settings page says WHY there is no control rather than
// offering one that refuses.
func TestWithNoStorageTheSettingsPageExplainsItself(t *testing.T) {
	td := teamDetail{Team: teamRow{Name: "core", Title: "Core"}, CanManage: true, Sect: "settings"}
	render := func(off, has bool) string {
		var buf strings.Builder
		if err := teamSettingsPage.Execute(&buf, pageData{Title: "Core · Settings",
			OwnH1: true, Team: &td, TeamBar: td.bar(),
			MarksOff: off, HasMark: has}); err != nil {
			t.Fatal(err)
		}
		return buf.String()
	}
	off := render(true, false)
	if !strings.Contains(off, `data-hook="marks-off"`) {
		t.Errorf("FAIL: no explanation where there is nowhere to put an image")
	}
	if strings.Contains(off, `type="file"`) {
		t.Errorf("FAIL: an upload control that cannot work was drawn anyway")
	}
	if !strings.Contains(off, "/fleet/settings") {
		t.Errorf("FAIL: the explanation does not say where to fix it")
	}
	// With storage, the control — and no Remove until there is
	// something to remove.
	on := render(false, false)
	if !strings.Contains(on, `type="file"`) || !strings.Contains(on, `action="/t/core/avatar"`) {
		t.Errorf("FAIL: no upload control where one would work")
	}
	if strings.Contains(on, `name="clear"`) {
		t.Errorf("FAIL: a Remove was offered with nothing to remove")
	}
	if !strings.Contains(render(false, true), `name="clear"`) {
		t.Errorf("FAIL: no Remove where there is an image")
	}
}