// SPDX-License-Identifier: AGPL-3.0-or-later
package app
import (
"fmt"
"os"
"path/filepath"
"strings"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"bnema.dev/ermite/internal/domain"
)
// AC1: the commit pages render for the fixtures with the structure of the
// mockup (golden HTML, normalised).
func TestWebCommitGolden(t *testing.T) {
h := newHarness(t, harnessOpts{})
f := h.diffRepo("diffs")
for _, tt := range []struct{ name, path string }{
{"commit-modify", "/diffs/commit/" + f.modify},
{"commit-modify-split", "/diffs/commit/" + f.modify + "?view=split"},
{"commit-root", "/diffs/commit/" + f.root},
{"commit-rename", "/diffs/commit/" + f.rename},
{"commit-binary", "/diffs/commit/" + f.binary},
{"commit-merge", "/diffs/commit/" + f.merge},
{"commit-trojan", "/diffs/commit/" + f.trojan},
{"commit-big", "/diffs/commit/" + f.big},
} {
t.Run(tt.name, func(t *testing.T) {
status, hdr, body := h.get(tt.path)
require.Equal(t, 200, status)
assert.Equal(t, "no-cache", hdr.Get("Cache-Control"))
assertNoInline(t, body)
golden(t, tt.name, normalise(body))
})
}
}
// The behaviours of the commit pages, asserted on their own.
func TestWebCommit(t *testing.T) {
h := newHarness(t, harnessOpts{})
f := h.diffRepo("diffs")
get := func(path string, status int) string {
t.Helper()
st, _, body := h.get(path)
require.Equal(t, status, st, path)
return body
}
t.Run("commit", func(t *testing.T) {
body := get("/diffs/commit/"+f.modify, 200)
assert.Contains(t, body, "
modify a file and make a script executable
")
assert.Contains(t, body, "The body has a second paragraph.")
assert.Contains(t, body, "And <b>html</b> &", "the message is text")
assert.NotContains(t, body, "html")
assert.Contains(t, body, "mode 100644 → 100755")
assert.Contains(t, body, `+ | `, "added lines keep their marker")
assert.Contains(t, body, `- | `, "deleted lines keep their marker")
assert.Contains(t, body, `data-diff="unified"`)
assert.Contains(t, body, `hx-live="this.dataset.diff = sessionStorage`, "the browser remembers the layout when the URL does not choose")
assert.Contains(t, body, `]* open`, body, "a truncated file is collapsed")
assert.NotContains(t, body, "line 2000", "no lines of a truncated file")
})
t.Run("not found", func(t *testing.T) {
_, _, missing := h.get("/diffs/commit/0123456789abcdef0123456789abcdef01234567")
for _, p := range []string{
"/diffs/commit/0123456789abcdef0123456789abcdef01234567", // no such commit
"/diffs/commit/main", "/diffs/commit/abc", "/diffs/commit/ABCDEF0", "/diffs/commit/v1.0.0", // not a commit id
"/nope/commit/" + f.root, "/diffs/commit/" + f.root + "/x",
} {
st, _, body := h.get(p)
assert.Equal(t, 404, st, p)
assert.NotContains(t, body, "root", p)
}
st, _, body := h.get("/diffs/commit/0123456789abcdef0123456789abcdef01234567")
assert.Equal(t, 404, st)
assert.Equal(t, normalise(missing), normalise(body))
})
}
// Over 4,000 lines only one layout is sent, the one the URL asks for.
func TestWebCommitLargeDiffView(t *testing.T) {
h := newHarness(t, harnessOpts{})
h.seed("large", domain.VisibilityPublic)
wt := h.workTree("main", "README")
var lines strings.Builder
for i := range 1500 {
fmt.Fprintf(&lines, "line %d\n", i)
}
for _, name := range []string{"a.txt", "b.txt", "c.txt"} {
require.NoError(t, os.WriteFile(filepath.Join(wt, name), []byte(lines.String()), 0o644))
}
h.mustGit(wt, "add", ".")
h.mustGit(wt, "commit", "-q", "-m", "three big files")
h.mustGit(wt, "push", "-q", h.urlAuth(adminToken, "/large.git"), "main")
sha := strings.TrimSpace(h.mustGit(wt, "rev-parse", "HEAD"))
_, _, unified := h.get("/large/commit/" + sha)
assert.True(t, strings.Contains(unified, `
`))
}
// AC2: the commit pages of a private repository are the 404 page of a
// repository that does not exist.
func TestWebCommitPrivate(t *testing.T) {
h := newHarness(t, harnessOpts{})
wt := h.workTree("main", "secret.txt")
h.createRepo("hidden-one", domain.VisibilityPrivate)
h.mustGit(wt, "push", "-q", h.urlAuth(adminToken, "/hidden-one.git"), "main")
sha := strings.TrimSpace(h.mustGit(wt, "rev-parse", "HEAD"))
_, _, missing := h.get("/never-existed")
for _, p := range []string{
"/hidden-one/commit/" + sha, "/hidden-one/commit/" + sha + "?view=split",
} {
st, hdr, body := h.get(p)
assert.Equal(t, 404, st, p)
assert.Equal(t, "no-cache", hdr.Get("Cache-Control"), p)
assert.NotContains(t, body, "hidden-one", p)
assert.NotContains(t, body, "secret.txt", p)
assert.Equal(t, normalise(missing), normalise(body), p)
}
}