josie / simplegit

package web

import (
	"net/http"
	"net/url"
	"os"
	"path/filepath"
	"strings"
	"testing"
)

func TestRepoSettingsRequiresOwner(t *testing.T) {
	httpServer, database, _ := newTestServer(t)
	createRepo(t, newLoggedInClient(t, httpServer), httpServer, "pub", "public")
	addUser(t, database, "mallory", "pw")

	resp, err := noFollowClient().Get(httpServer.URL + "/josie/pub/settings")
	if err != nil {
		t.Fatalf("anonymous GET settings: %v", err)
	}
	readAll(t, resp)
	if resp.StatusCode != http.StatusSeeOther || resp.Header.Get("Location") != "/login" {
		t.Errorf("anonymous settings = %d %q, want 303 /login", resp.StatusCode, resp.Header.Get("Location"))
	}

	mallory := loginAs(t, httpServer, "mallory", "pw")
	resp, err = mallory.Get(httpServer.URL + "/josie/pub/settings")
	if err != nil {
		t.Fatalf("non-owner GET settings: %v", err)
	}
	readAll(t, resp)
	if resp.StatusCode != http.StatusNotFound {
		t.Errorf("non-owner settings = %d, want 404", resp.StatusCode)
	}

	owner := newLoggedInClient(t, httpServer)
	resp, err = owner.Get(httpServer.URL + "/josie/pub/settings")
	if err != nil {
		t.Fatalf("owner GET settings: %v", err)
	}
	if body := readAll(t, resp); resp.StatusCode != http.StatusOK || !strings.Contains(body, "visibility") {
		t.Errorf("owner settings = %d, body %q", resp.StatusCode, body)
	}
}

func TestRepoSettingsVisibilityRenameDelete(t *testing.T) {
	httpServer, _, dataDir := newTestServer(t)
	owner := newLoggedInClient(t, httpServer)
	createRepo(t, owner, httpServer, "pub", "public")
	seedFiles(t, dataDir, "pub")

	// Visibility: public -> private hides it from anonymous readers.
	resp, err := owner.PostForm(httpServer.URL+"/josie/pub/settings/visibility", url.Values{"visibility": {"private"}})
	if err != nil {
		t.Fatalf("set private: %v", err)
	}
	readAll(t, resp)
	anon, err := noFollowClient().Get(httpServer.URL + "/josie/pub")
	if err != nil {
		t.Fatalf("anon read after private: %v", err)
	}
	readAll(t, anon)
	if anon.StatusCode != http.StatusNotFound {
		t.Errorf("anon read private repo = %d, want 404 (no existence oracle)", anon.StatusCode)
	}

	// Rename moves the directory and the row.
	resp, err = owner.PostForm(httpServer.URL+"/josie/pub/settings/rename", url.Values{"name": {"renamed"}})
	if err != nil {
		t.Fatalf("rename: %v", err)
	}
	readAll(t, resp)
	if _, err := os.Stat(filepath.Join(dataDir, "repos", "josie", "pub.git")); !os.IsNotExist(err) {
		t.Errorf("old repo dir still present (err %v)", err)
	}
	if _, err := os.Stat(filepath.Join(dataDir, "repos", "josie", "renamed.git")); err != nil {
		t.Errorf("new repo dir missing: %v", err)
	}
	resp, err = owner.Get(httpServer.URL + "/josie/renamed")
	if err != nil {
		t.Fatalf("owner GET renamed: %v", err)
	}
	if body := readAll(t, resp); resp.StatusCode != http.StatusOK || !strings.Contains(body, "README.md") {
		t.Errorf("renamed repo home = %d, body %q", resp.StatusCode, body)
	}
	resp, err = (&http.Client{}).Get(httpServer.URL + "/josie/pub")
	if err != nil {
		t.Fatalf("GET old name: %v", err)
	}
	readAll(t, resp)
	if resp.StatusCode != http.StatusNotFound {
		t.Errorf("old repo URL = %d, want 404", resp.StatusCode)
	}

	// Duplicate rename is rejected.
	createRepo(t, owner, httpServer, "other", "private")
	resp, err = owner.PostForm(httpServer.URL+"/josie/renamed/settings/rename", url.Values{"name": {"other"}})
	if err != nil {
		t.Fatalf("duplicate rename: %v", err)
	}
	if body := readAll(t, resp); resp.StatusCode != http.StatusUnprocessableEntity || !strings.Contains(body, "already have a repository") {
		t.Errorf("duplicate rename = %d, body %q", resp.StatusCode, body)
	}

	// Delete removes the directory and the row.
	resp, err = owner.PostForm(httpServer.URL+"/josie/other/settings/delete", nil)
	if err != nil {
		t.Fatalf("delete: %v", err)
	}
	readAll(t, resp)
	if _, err := os.Stat(filepath.Join(dataDir, "repos", "josie", "other.git")); !os.IsNotExist(err) {
		t.Errorf("deleted repo dir still present (err %v)", err)
	}
	resp, err = owner.Get(httpServer.URL + "/josie/other")
	if err != nil {
		t.Fatalf("GET deleted repo: %v", err)
	}
	readAll(t, resp)
	if resp.StatusCode != http.StatusNotFound {
		t.Errorf("deleted repo URL = %d, want 404", resp.StatusCode)
	}
}