1package archesrv
2
3import (
4 "io"
5 "net/http"
6 "strings"
7 "testing"
8)
9
10func TestForgeServer_Wiki_SaveAndFetch(t *testing.T) {
11 s, ts := newTestServer(t)
12 _, client := loginAsAdmin(t, s, ts)
13 setupRepoWithDisk(t, s, "myrepo", "private")
14
15 resp, err := client.PostForm(ts.URL+"/myrepo/wiki/Home", map[string][]string{
16 "content": {"# Hello\n\nThis is the home page."},
17 })
18 if err != nil {
19 t.Fatalf("POST wiki: %v", err)
20 }
21 resp.Body.Close()
22 if resp.StatusCode >= 400 {
23 t.Errorf("wiki save: got %d", resp.StatusCode)
24 }
25
26 resp2, err := client.Get(ts.URL + "/myrepo/wiki/Home")
27 if err != nil {
28 t.Fatalf("GET wiki: %v", err)
29 }
30 defer resp2.Body.Close()
31 if resp2.StatusCode != http.StatusOK {
32 t.Errorf("wiki get: want 200, got %d", resp2.StatusCode)
33 }
34 body, _ := io.ReadAll(resp2.Body)
35 if !strings.Contains(string(body), "Hello") {
36 t.Error("wiki page should contain saved content")
37 }
38}
39
40func TestForgeServer_Wiki_ListShowsPage(t *testing.T) {
41 s, ts := newTestServer(t)
42 _, client := loginAsAdmin(t, s, ts)
43 setupRepoWithDisk(t, s, "myrepo", "private")
44
45 client.PostForm(ts.URL+"/myrepo/wiki/MyPage", map[string][]string{"content": {"hello"}}) //nolint:errcheck
46
47 resp, err := client.Get(ts.URL + "/myrepo/wiki")
48 if err != nil {
49 t.Fatalf("GET wiki list: %v", err)
50 }
51 defer resp.Body.Close()
52 if resp.StatusCode != http.StatusOK {
53 t.Errorf("wiki list: want 200, got %d", resp.StatusCode)
54 }
55 body, _ := io.ReadAll(resp.Body)
56 if !strings.Contains(string(body), "MyPage") {
57 t.Error("wiki list should contain the page name")
58 }
59}
60
61func TestForgeServer_Wiki_UnauthenticatedCannotSave(t *testing.T) {
62 s, ts := newTestServer(t)
63 setupRepoWithDisk(t, s, "myrepo", "public")
64
65 resp, err := http.PostForm(ts.URL+"/myrepo/wiki/Home", map[string][]string{
66 "content": {"malicious content"},
67 })
68 if err != nil {
69 t.Fatalf("POST: %v", err)
70 }
71 resp.Body.Close()
72 if resp.StatusCode != http.StatusUnauthorized {
73 t.Errorf("expected 401, got %d", resp.StatusCode)
74 }
75}
76
77func TestForgeServer_Wiki_PageNotFoundShows200(t *testing.T) {
78 s, ts := newTestServer(t)
79 _, client := loginAsAdmin(t, s, ts)
80 setupRepoWithDisk(t, s, "myrepo", "private")
81
82 resp, err := client.Get(ts.URL + "/myrepo/wiki/DoesNotExist")
83 if err != nil {
84 t.Fatalf("GET: %v", err)
85 }
86 defer resp.Body.Close()
87 if resp.StatusCode != http.StatusOK {
88 t.Errorf("nonexistent wiki page: want 200 (new-page form), got %d", resp.StatusCode)
89 }
90}
91
92func TestForgeServer_Wiki_OverwritePage(t *testing.T) {
93 s, ts := newTestServer(t)
94 _, client := loginAsAdmin(t, s, ts)
95 setupRepoWithDisk(t, s, "myrepo", "private")
96
97 r1, _ := client.PostForm(ts.URL+"/myrepo/wiki/Notes", map[string][]string{"content": {"v1 content"}})
98 r1.Body.Close()
99
100 r2, _ := client.PostForm(ts.URL+"/myrepo/wiki/Notes", map[string][]string{"content": {"v2 content"}})
101 r2.Body.Close()
102
103 resp, err := client.Get(ts.URL + "/myrepo/wiki/Notes")
104 if err != nil {
105 t.Fatalf("GET: %v", err)
106 }
107 defer resp.Body.Close()
108 body, _ := io.ReadAll(resp.Body)
109 if !strings.Contains(string(body), "v2 content") {
110 t.Error("wiki page should show updated content")
111 }
112}
113
114func TestForgeServer_Wiki_MissingRepo404(t *testing.T) {
115 s, ts := newTestServer(t)
116 s.db.CreateUser("admin", "adminpass", true) //nolint:errcheck
117 client := loginAs(t, ts, "admin", "adminpass")
118
119 resp, err := client.Get(ts.URL + "/ghost/wiki")
120 if err != nil {
121 t.Fatalf("GET: %v", err)
122 }
123 resp.Body.Close()
124 if resp.StatusCode != http.StatusNotFound {
125 t.Errorf("missing repo: want 404, got %d", resp.StatusCode)
126 }
127}
128
129func TestForgeServer_Wiki_PublicRepoAnonCanReadWiki(t *testing.T) {
130 s, ts := newTestServer(t)
131 _, client := loginAsAdmin(t, s, ts)
132 setupRepoWithDisk(t, s, "myrepo", "public")
133
134 client.PostForm(ts.URL+"/myrepo/wiki/Public", map[string][]string{"content": {"public content"}}) //nolint:errcheck
135
136 resp, err := http.Get(ts.URL + "/myrepo/wiki/Public")
137 if err != nil {
138 t.Fatalf("GET: %v", err)
139 }
140 defer resp.Body.Close()
141 if resp.StatusCode != http.StatusOK {
142 t.Errorf("public wiki: anon should get 200, got %d", resp.StatusCode)
143 }
144 body, _ := io.ReadAll(resp.Body)
145 if !strings.Contains(string(body), "public content") {
146 t.Error("public wiki page should show content for anon")
147 }
148}