fierj
PublicTiny personal git forge
package main
import (
"net/http"
"net/url"
"strings"
"testing"
)
// ---------- Access Control ----------
// TestAnonymousCannotCreateRepo verifies /new redirects to login for anon users.
func TestAnonymousCannotCreateRepo(t *testing.T) {
ts := newTestServer(t)
adminClient := ts.client()
ts.setupUser(t, adminClient, "admin", "admin123")
anonClient := ts.client()
// Anon tries to access /new — should be redirected to login
resp := ts.get(t, anonClient, "/new")
assertStatus(t, resp, http.StatusOK)
b := body(t, resp)
if strings.Contains(b, "Create") && !strings.Contains(b, "Sign in") {
t.Error("anonymous user should be redirected to login from /new")
}
}
// TestAnonymousCannotAccessSettings verifies settings redirect for anon.
func TestAnonymousCannotAccessSettings(t *testing.T) {
ts := newTestServer(t)
adminClient := ts.client()
ts.setupUser(t, adminClient, "admin", "admin123")
ts.createRepo(t, adminClient, "pub", "Public repo")
anonClient := ts.client()
resp := ts.get(t, anonClient, "/pub/settings")
assertStatus(t, resp, http.StatusOK)
b := body(t, resp)
if !strings.Contains(b, "Sign in") {
t.Error("anonymous should be redirected to login for settings")
}
}
// TestAnonymousCanViewPublicThreads verifies threads are visible on public repos.
func TestAnonymousCanViewPublicThreads(t *testing.T) {
ts := newTestServer(t)
adminClient := ts.client()
ts.setupUser(t, adminClient, "admin", "admin123")
ts.createRepo(t, adminClient, "discuss", "Discussion repo")
// Create a thread as admin
resp := ts.postForm(t, adminClient, "/discuss/threads/new", url.Values{
"title": {"Public discussion"},
"body": {"Anyone can read this."},
})
assertStatus(t, resp, http.StatusOK)
// Get thread ID
rp := repoPath(ts.cfg, "discuss")
threads, _, _ := listThreadsFiltered(rp, "open")
if len(threads) != 1 {
t.Fatalf("expected 1 thread, got %d", len(threads))
}
// Anon can view the thread
anonClient := ts.client()
resp = ts.get(t, anonClient, "/discuss/threads/"+threads[0].ID)
assertStatus(t, resp, http.StatusOK)
b := body(t, resp)
if !strings.Contains(b, "Public discussion") {
t.Error("anonymous should see public thread")
}
}
// TestAnonymousCanViewPublicPatches verifies patches are visible on public repos.
func TestAnonymousCanViewPublicPatches(t *testing.T) {
ts := newTestServer(t)
adminClient := ts.client()
ts.setupUser(t, adminClient, "admin", "admin123")
ts.createRepo(t, adminClient, "patches", "Patches repo")
// Push something so we have a branch
localDir := t.TempDir()
bareRepo := repoPath(ts.cfg, "patches")
gitCmd(t, localDir, "clone", "file://"+bareRepo, "repo")
localRepo := localDir + "/repo"
writeFile(t, localRepo, "f.txt", "hello")
gitCmd(t, localRepo, "add", "f.txt")
gitCmd(t, localRepo, "commit", "-m", "init")
gitCmd(t, localRepo, "push", "origin", "main")
gitCmd(t, localRepo, "checkout", "-b", "fix")
writeFile(t, localRepo, "f.txt", "fixed")
gitCmd(t, localRepo, "add", "f.txt")
gitCmd(t, localRepo, "commit", "-m", "fix")
gitCmd(t, localRepo, "push", "origin", "fix")
// Create a patch
resp := ts.postForm(t, adminClient, "/patches/patches/new", url.Values{
"title": {"Test patch"},
"body": {"Patch body"},
"branch": {"fix"},
})
assertStatus(t, resp, http.StatusOK)
rp := repoPath(ts.cfg, "patches")
patches, _ := listPatches(rp, "open")
if len(patches) != 1 {
t.Fatalf("expected 1 patch, got %d", len(patches))
}
// Anon can view
anonClient := ts.client()
resp = ts.get(t, anonClient, "/patches/patches/"+patches[0].ID)
assertStatus(t, resp, http.StatusOK)
b := body(t, resp)
if !strings.Contains(b, "Test patch") {
t.Error("anonymous should see public patch")
}
}
// TestLoggedInSeesPrivateRepos verifies private repos appear for authenticated users.
func TestLoggedInSeesPrivateRepos(t *testing.T) {
ts := newTestServer(t)
c := ts.client()
ts.setupUser(t, c, "alice", "pass123")
ts.createRepo(t, c, "secret", "Private repo")
// Make it private
ts.postForm(t, c, "/secret/settings", url.Values{
"description": {"Private repo"},
"is_private": {"true"},
})
// Logged-in user sees it on home page
resp := ts.get(t, c, "/")
assertStatus(t, resp, http.StatusOK)
b := body(t, resp)
if !strings.Contains(b, "secret") {
t.Error("logged-in user should see private repos on home page")
}
}
// TestAnonCannotCreateThreadOnPrivateRepo verifies POST requires login on private repos.
func TestAnonCannotCreateThreadOnPrivateRepo(t *testing.T) {
ts := newTestServer(t)
adminClient := ts.client()
ts.setupUser(t, adminClient, "admin", "admin123")
ts.createRepo(t, adminClient, "priv", "Private")
// Make it private
ts.postForm(t, adminClient, "/priv/settings", url.Values{
"description": {"Private"},
"is_private": {"true"},
})
anonClient := ts.client()
resp := ts.postForm(t, anonClient, "/priv/threads/new", url.Values{
"title": {"Should not work"},
"body": {"Anon thread"},
})
assertStatus(t, resp, http.StatusOK)
b := body(t, resp)
if !strings.Contains(b, "Sign in") {
t.Error("anonymous should not create threads on private repos")
}
}
// TestAnonCannotCreatePatchOnPrivateRepo verifies POST requires login on private repos.
func TestAnonCannotCreatePatchOnPrivateRepo(t *testing.T) {
ts := newTestServer(t)
adminClient := ts.client()
ts.setupUser(t, adminClient, "admin", "admin123")
ts.createRepo(t, adminClient, "priv", "Private")
// Make it private
ts.postForm(t, adminClient, "/priv/settings", url.Values{
"description": {"Private"},
"is_private": {"true"},
})
anonClient := ts.client()
resp := ts.postForm(t, anonClient, "/priv/patches/new", url.Values{
"title": {"Should not work"},
"body": {"Anon patch"},
})
assertStatus(t, resp, http.StatusOK)
b := body(t, resp)
if !strings.Contains(b, "Sign in") {
t.Error("anonymous should not create patches on private repos")
}
}