b93e14ae88f05c6e01d25ab41d2ecb7456d769b3 / internal/web/repo_test.go · 3934 bytes · raw
package web
import (
"net/http"
"net/url"
"os"
"path/filepath"
"strings"
"testing"
"git.josie-c.com/josie/simplegit/internal/db"
)
func TestNewRepoFormRequiresLogin(t *testing.T) {
httpServer, _, _ := newTestServer(t)
client := &http.Client{CheckRedirect: func(*http.Request, []*http.Request) error {
return http.ErrUseLastResponse
}}
resp, err := client.Get(httpServer.URL + "/new")
if err != nil {
t.Fatalf("GET /new: %v", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusSeeOther {
t.Errorf("status = %d, want 303", resp.StatusCode)
}
if resp.Header.Get("Location") != "/login" {
t.Errorf("Location = %q, want /login", resp.Header.Get("Location"))
}
loggedIn := newLoggedInClient(t, httpServer)
resp, err = loggedIn.Get(httpServer.URL + "/new")
if err != nil {
t.Fatalf("GET /new signed in: %v", err)
}
body := readAll(t, resp)
if resp.StatusCode != http.StatusOK || !strings.Contains(body, `name="name"`) {
t.Errorf("signed-in GET /new = %d, form missing: %q", resp.StatusCode, body)
}
}
func TestCreateRepoFlow(t *testing.T) {
httpServer, database, dataDir := newTestServer(t)
client := newLoggedInClient(t, httpServer)
resp, err := client.PostForm(httpServer.URL+"/new", url.Values{
"name": {"my-repo"}, "description": {"a test repo"}, "visibility": {"public"},
})
if err != nil {
t.Fatalf("POST /new: %v", err)
}
body := readAll(t, resp)
if resp.StatusCode != http.StatusOK {
t.Errorf("status = %d, want 200", resp.StatusCode)
}
if !strings.Contains(body, "git remote add origin") || !strings.Contains(body, "/josie/my-repo.git") {
t.Errorf("no push instructions: %q", body)
}
repo, err := db.GetRepoByName(database, "josie", "my-repo")
if err != nil {
t.Fatalf("GetRepoByName: %v", err)
}
if repo.Visibility != "public" || repo.Description != "a test repo" {
t.Errorf("repo = %+v, want public / %q stored", repo, "a test repo")
}
if repo.PushedAt.Valid {
t.Errorf("PushedAt = %d, want NULL before first push", repo.PushedAt.Int64)
}
head, err := os.ReadFile(filepath.Join(dataDir, "repos", "josie", "my-repo.git", "HEAD"))
if err != nil {
t.Fatalf("bare repo HEAD missing: %v", err)
}
if !strings.Contains(string(head), "ref: refs/heads/"+repo.DefaultBranch) {
t.Errorf("HEAD = %q, want default branch %q", head, repo.DefaultBranch)
}
}
func TestCreateRepoRejectsBadNames(t *testing.T) {
httpServer, _, _ := newTestServer(t)
client := newLoggedInClient(t, httpServer)
for _, name := range []string{"bad name", "ünicode", "", strings.Repeat("a", maxNameLen+1)} {
resp, err := client.PostForm(httpServer.URL+"/new", url.Values{"name": {name}})
if err != nil {
t.Fatalf("POST /new %q: %v", name, err)
}
body := readAll(t, resp)
if resp.StatusCode != http.StatusUnprocessableEntity {
t.Errorf("name %q: status = %d, want 422", name, resp.StatusCode)
}
if !strings.Contains(body, "invalid repository name") {
t.Errorf("name %q: no error shown: %q", name, body)
}
}
}
func TestCreateRepoRejectsDuplicate(t *testing.T) {
httpServer, database, _ := newTestServer(t)
client := newLoggedInClient(t, httpServer)
resp, err := client.PostForm(httpServer.URL+"/new", url.Values{"name": {"dup"}})
if err != nil {
t.Fatalf("first POST /new: %v", err)
}
readAll(t, resp)
resp, err = client.PostForm(httpServer.URL+"/new", url.Values{"name": {"dup"}})
if err != nil {
t.Fatalf("second POST /new: %v", err)
}
body := readAll(t, resp)
if resp.StatusCode != http.StatusUnprocessableEntity {
t.Errorf("status = %d, want 422", resp.StatusCode)
}
if !strings.Contains(body, "already have a repository") {
t.Errorf("no duplicate error shown: %q", body)
}
var count int
if err := database.QueryRow(
`SELECT count(*) FROM repos WHERE name = ?`, "dup",
).Scan(&count); err != nil {
t.Fatalf("count repos: %v", err)
}
if count != 1 {
t.Errorf("repos named dup = %d, want 1", count)
}
}