e2e/archive_test.go

v1.25.0
gitbay/e2e/archive_test.go history · blame · raw

134 lines · 5924 bytes

  1package e2e
  2
  3import (
  4	"os"
  5	"path/filepath"
  6	"strings"
  7	"testing"
  8)
  9
 10func TestArchiveAndTopics(t *testing.T) {
 11	inst := startInstance(t)
 12	aliceKey := inst.newKey(t, "alice")
 13	bobKey := inst.newKey(t, "bob")
 14	inst.admin(t, "admin", "user", "create", "alice",
 15		"--key", aliceKey+".pub", "--email", "alice@example.test", "--verified")
 16	inst.admin(t, "admin", "user", "create", "bob", "--key", bobKey+".pub")
 17
 18	if _, errOut, code := inst.ssh(t, aliceKey, "", "repo", "create", "alice/app"); code != 0 {
 19		t.Fatalf("repo create: %s", errOut)
 20	}
 21	if _, _, code := inst.ssh(t, aliceKey, "", "repo", "access", "grant", "alice/app", "bob", "write"); code != 0 {
 22		t.Fatal("grant failed")
 23	}
 24	work := t.TempDir()
 25	env := inst.gitEnv(aliceKey)
 26	mustGit(t, work, env, "clone", inst.sshURL("alice/app"), "w")
 27	dir := filepath.Join(work, "w")
 28	os.WriteFile(filepath.Join(dir, "a.txt"), []byte("a\n"), 0o644)
 29	mustGit(t, dir, env, "checkout", "-q", "-b", "main")
 30	mustGit(t, dir, env, "add", ".")
 31	mustGit(t, dir, env, "commit", "-q", "-m", "base")
 32	mustGit(t, dir, env, "push", "-q", "origin", "main")
 33
 34	// Topics: admin-only edits, validation, idempotent add, listing.
 35	if _, errOut, code := inst.ssh(t, bobKey, "", "repo", "topics", "add", "alice/app", "go"); code != 4 {
 36		t.Fatalf("non-admin added topics: exit %d, %s", code, errOut)
 37	}
 38	if _, errOut, code := inst.ssh(t, aliceKey, "", "repo", "topics", "add", "alice/app", "Bad_Topic"); code != 2 || !strings.Contains(errOut, "invalid topic") {
 39		t.Fatalf("bad topic accepted: exit %d, %s", code, errOut)
 40	}
 41	if _, errOut, code := inst.ssh(t, aliceKey, "", "repo", "topics", "add", "alice/app", "go", "cli", "go"); code != 0 {
 42		t.Fatalf("topics add: %s", errOut)
 43	}
 44	out, _, _ := inst.ssh(t, aliceKey, "", "repo", "topics", "alice/app", "--json")
 45	if !strings.Contains(out, `["cli","go"]`) {
 46		t.Fatalf("topics list: %s", out)
 47	}
 48	out, _, _ = inst.ssh(t, aliceKey, "", "repo", "show", "alice/app", "--json")
 49	if !strings.Contains(out, `"topics":["cli","go"]`) || strings.Contains(out, `"archived"`) {
 50		t.Fatalf("repo show topics: %s", out)
 51	}
 52	if _, _, code := inst.ssh(t, aliceKey, "", "repo", "topics", "remove", "alice/app", "cli"); code != 0 {
 53		t.Fatal("topics remove failed")
 54	}
 55	if _, _, code := inst.ssh(t, aliceKey, "", "repo", "topics", "remove", "alice/app", "cli"); code != 3 {
 56		t.Fatal("removing an absent topic should be not-found")
 57	}
 58
 59	// An MR and an issue that predate archiving.
 60	mustGit(t, dir, env, "checkout", "-q", "-b", "feat")
 61	os.WriteFile(filepath.Join(dir, "b.txt"), []byte("b\n"), 0o644)
 62	mustGit(t, dir, env, "add", ".")
 63	mustGit(t, dir, env, "commit", "-q", "-m", "feat")
 64	mustGit(t, dir, env, "push", "-q", "origin", "feat")
 65	if _, errOut, code := inst.ssh(t, aliceKey, "", "mr", "create", "alice/app",
 66		"--source", "feat", "--target", "main", "--title", "'feat'"); code != 0 {
 67		t.Fatalf("mr create: %s", errOut)
 68	}
 69	if _, errOut, code := inst.ssh(t, aliceKey, "", "issue", "create", "alice/app", "--title", "'todo'"); code != 0 {
 70		t.Fatalf("issue create: %s", errOut)
 71	}
 72
 73	// Archive: admin-only, then everything content-mutating is refused.
 74	if _, _, code := inst.ssh(t, bobKey, "", "repo", "archive", "alice/app"); code != 4 {
 75		t.Fatal("non-admin archived the repo")
 76	}
 77	if _, errOut, code := inst.ssh(t, aliceKey, "", "repo", "archive", "alice/app"); code != 0 {
 78		t.Fatalf("archive: %s", errOut)
 79	}
 80	if _, _, code := inst.ssh(t, aliceKey, "", "repo", "archive", "alice/app"); code != 2 {
 81		t.Fatal("double archive not refused")
 82	}
 83
 84	os.WriteFile(filepath.Join(dir, "c.txt"), []byte("c\n"), 0o644)
 85	mustGit(t, dir, env, "checkout", "-q", "main")
 86	mustGit(t, dir, env, "add", ".")
 87	mustGit(t, dir, env, "commit", "-q", "-m", "more")
 88	if out, code := gitRun(t, dir, env, "push", "origin", "main"); code == 0 || !strings.Contains(out, "archived and read-only") {
 89		t.Fatalf("push to archived repo: exit %d\n%s", code, out)
 90	}
 91	for _, cmd := range [][]string{
 92		{"issue", "create", "alice/app", "--title", "'x'"},
 93		{"issue", "comment", "alice/app", "1", "--message", "'x'"},
 94		{"issue", "close", "alice/app", "1"},
 95		{"mr", "comment", "alice/app", "1", "--message", "'x'"},
 96		{"mr", "review", "alice/app", "1", "--approve"},
 97		{"mr", "merge", "alice/app", "1"},
 98		{"mr", "close", "alice/app", "1"},
 99		{"status", "set", "alice/app", "HEAD", "--context", "ci", "--state", "success"},
100	} {
101		if _, errOut, code := inst.ssh(t, bobKey, "", cmd...); code != 4 || !strings.Contains(errOut, "archived and read-only") {
102			t.Fatalf("%v on archived repo: exit %d, %s", cmd, code, errOut)
103		}
104	}
105
106	// Reading stays untouched: clone, listings, show, web.
107	work2 := t.TempDir()
108	mustGit(t, work2, env, "clone", "-q", inst.sshURL("alice/app"), "r")
109	if out, _, code := inst.ssh(t, aliceKey, "", "issue", "list", "alice/app"); code != 0 || !strings.Contains(out, "todo") {
110		t.Fatalf("issue list on archived repo: %s", out)
111	}
112	out, _, _ = inst.ssh(t, aliceKey, "", "repo", "show", "alice/app", "--json")
113	if !strings.Contains(out, `"archived":true`) {
114		t.Fatalf("repo show archived flag: %s", out)
115	}
116	if status, _ := inst.get(t, "/alice/app"); status != 200 {
117		t.Fatalf("web browse on archived repo: %d", status)
118	}
119
120	// Settings and unarchive still work; writes come back.
121	if _, _, code := inst.ssh(t, aliceKey, "", "repo", "settings", "protect", "alice/app", "main"); code != 0 {
122		t.Fatal("settings on archived repo should still work")
123	}
124	if _, _, code := inst.ssh(t, aliceKey, "", "repo", "settings", "unprotect", "alice/app", "main"); code != 0 {
125		t.Fatal("unprotect failed")
126	}
127	if _, errOut, code := inst.ssh(t, aliceKey, "", "repo", "unarchive", "alice/app"); code != 0 {
128		t.Fatalf("unarchive: %s", errOut)
129	}
130	mustGit(t, dir, env, "push", "-q", "origin", "main")
131	if _, errOut, code := inst.ssh(t, bobKey, "", "issue", "comment", "alice/app", "1", "--message", "'back'"); code != 0 {
132		t.Fatalf("comment after unarchive: %s", errOut)
133	}
134}