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) } }