e2e/archive_test.go

e2a32d5f8d59e4213571c602bd9009b6c8fa86ed
gitbay/e2e/archive_test.go history · blame · raw

135 lines · 5938 bytes

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