e2e/bookmarks_test.go
109 lines · 4727 bytes
2 symbols in this file
1package e2e
2
3import (
4 "net/url"
5 "os"
6 "path/filepath"
7 "strings"
8 "testing"
9)
10
11// Bookmarks are the public "saved for later", separate from pins: they
12// are something you do to someone else's repository, and the count is a
13// signal of what people found worth returning to (#146).
14func TestBookmarks(t *testing.T) {
15 t.Parallel()
16 inst := startInstanceWith(t, "[web]\nmode = \"accounts\"\n")
17 aliceKey := inst.newKey(t, "alice")
18 bobKey := inst.newKey(t, "bob")
19 inst.admin(t, "admin", "user", "create", "alice", "--key", aliceKey+".pub")
20 inst.admin(t, "admin", "user", "create", "bob", "--key", bobKey+".pub")
21 if _, errOut, code := inst.ssh(t, aliceKey, "", "repo", "create", "alice/app"); code != 0 {
22 t.Fatalf("repo create: %s", errOut)
23 }
24 if _, errOut, code := inst.ssh(t, aliceKey, "", "repo", "create", "alice/secret", "--private"); code != 0 {
25 t.Fatalf("repo create: %s", errOut)
26 }
27 // The facts bar, where the count shows, needs a repository with
28 // commits: an empty one has nothing to size up.
29 env := inst.gitEnv(aliceKey)
30 work := t.TempDir()
31 mustGit(t, work, env, "clone", inst.sshURL("alice/app"), "w")
32 dir := filepath.Join(work, "w")
33 os.WriteFile(filepath.Join(dir, "a.txt"), []byte("a\n"), 0o644)
34 mustGit(t, dir, env, "checkout", "-q", "-b", "main")
35 mustGit(t, dir, env, "add", ".")
36 mustGit(t, dir, env, "commit", "-q", "-m", "base")
37 mustGit(t, dir, env, "push", "-q", "origin", "main")
38
39 // Bob bookmarks someone else's repository; read access is enough.
40 if out, errOut, code := inst.ssh(t, bobKey, "", "repo", "bookmark", "alice/app"); code != 0 {
41 t.Fatalf("bookmark: %s%s", out, errOut)
42 }
43 if out, _, _ := inst.ssh(t, bobKey, "", "repo", "bookmarks", "--json"); !strings.Contains(out, `"path":"alice/app"`) ||
44 !strings.Contains(out, `"bookmarks":1`) {
45 t.Fatalf("bookmark not listed with its count:\n%s", out)
46 }
47 // Bookmarking twice is not an error and does not double the count.
48 inst.ssh(t, bobKey, "", "repo", "bookmark", "alice/app")
49 if out, _, _ := inst.ssh(t, bobKey, "", "repo", "bookmarks", "--json"); !strings.Contains(out, `"bookmarks":1`) {
50 t.Fatalf("a second bookmark changed the count:\n%s", out)
51 }
52
53 // A private repository a stranger cannot read is not found, the same
54 // as everywhere.
55 if _, _, code := inst.ssh(t, bobKey, "", "repo", "bookmark", "alice/secret"); code != 3 {
56 t.Errorf("bookmarking an invisible repository exited %d, want 3", code)
57 }
58
59 // Pins stay separate: bookmarking does not pin.
60 if out, _, _ := inst.ssh(t, bobKey, "", "dashboard", "--json"); strings.Contains(out, "alice/app") {
61 t.Errorf("a bookmark showed up as a pin:\n%s", out)
62 }
63
64 // The count is public and shows on the repository page.
65 if _, body := inst.get(t, "/alice/app"); !strings.Contains(body, "1</b> bookmark") {
66 t.Errorf("count not on the repo page:\n%s", body)
67 }
68
69 // The web toggles it, through the same command.
70 bob := inst.login(t, bobKey)
71 if status, _ := browserPost(t, bob, inst.base()+"/alice/app/bookmark", url.Values{}); status != 200 {
72 t.Fatal("web unbookmark failed")
73 }
74 if out, _, _ := inst.ssh(t, bobKey, "", "repo", "bookmarks", "--json"); strings.Contains(out, "alice/app") {
75 t.Fatalf("still bookmarked after the toggle:\n%s", out)
76 }
77 if status, _ := browserPost(t, bob, inst.base()+"/alice/app/bookmark", url.Values{}); status != 200 {
78 t.Fatal("web bookmark failed")
79 }
80 if _, page := browserGet(t, bob, inst.base()+"/bookmarks"); !strings.Contains(page, "alice/app") {
81 t.Fatalf("bookmarks page does not list it:\n%s", page)
82 }
83
84 // Unbookmarking something that is not bookmarked says so.
85 if _, _, code := inst.ssh(t, aliceKey, "", "repo", "unbookmark", "alice/app"); code != 3 {
86 t.Errorf("unbookmarking what was never bookmarked exited %d, want 3", code)
87 }
88}
89
90// A repository bookmarked while public and since made private drops out
91// of the listing rather than leaking its existence.
92func TestBookmarkOfRepoGonePrivate(t *testing.T) {
93 t.Parallel()
94 inst := startInstance(t)
95 aliceKey := inst.newKey(t, "alice")
96 bobKey := inst.newKey(t, "bob")
97 inst.admin(t, "admin", "user", "create", "alice", "--key", aliceKey+".pub")
98 inst.admin(t, "admin", "user", "create", "bob", "--key", bobKey+".pub")
99 inst.ssh(t, aliceKey, "", "repo", "create", "alice/app")
100 if _, errOut, code := inst.ssh(t, bobKey, "", "repo", "bookmark", "alice/app"); code != 0 {
101 t.Fatalf("bookmark: %s", errOut)
102 }
103 if _, errOut, code := inst.ssh(t, aliceKey, "", "repo", "settings", "visibility", "alice/app", "private"); code != 0 {
104 t.Fatalf("visibility: %s", errOut)
105 }
106 if out, _, _ := inst.ssh(t, bobKey, "", "repo", "bookmarks", "--json"); strings.Contains(out, "alice/app") {
107 t.Fatalf("a repository gone private is still listed:\n%s", out)
108 }
109}