gitcat
1package server
2
3import (
4 "net/http"
5 "net/http/httptest"
6 "net/url"
7 "regexp"
8 "strings"
9 "testing"
10)
11
12var csrfRe = regexp.MustCompile(`name="csrf" value="([^"]+)"`)
13
14func login(t *testing.T, srv *Server, user, pass string) *httptest.ResponseRecorder {
15 t.Helper()
16 r := httptest.NewRequest(http.MethodPost, "/login",
17 strings.NewReader(url.Values{"username": {user}, "password": {pass}}.Encode()))
18 r.Header.Set("Content-Type", "application/x-www-form-urlencoded")
19 w := httptest.NewRecorder()
20 srv.Handler().ServeHTTP(w, r)
21 if w.Code != http.StatusFound && w.Code != http.StatusOK {
22 t.Fatalf("登录 %s 返回 %d", user, w.Code)
23 }
24 return w
25}
26
27func csrfOf(t *testing.T, srv *Server, path, cookie string) string {
28 t.Helper()
29 r := httptest.NewRequest(http.MethodGet, path, nil)
30 r.AddCookie(&http.Cookie{Name: SessionCookieName, Value: cookie})
31 w := httptest.NewRecorder()
32 srv.Handler().ServeHTTP(w, r)
33 m := csrfRe.FindStringSubmatch(w.Body.String())
34 if m == nil {
35 t.Fatalf("页面 %s 里找不到 csrf", path)
36 }
37 return m[1]
38}
39
40func sessionCookie(t *testing.T, w *httptest.ResponseRecorder) string {
41 t.Helper()
42 for _, c := range w.Result().Cookies() {
43 if c.Name == SessionCookieName {
44 return c.Value
45 }
46 }
47 t.Fatal("登录响应里没有会话 Cookie")
48 return ""
49}
50
51// TestRepoSettingsRenameIsAtomic 回归:改名成功后,同一请求里的后续校验
52// 曾因继续使用已失效的旧目录而返回 400,把成功的改名报成失败。
53func TestRepoSettingsRenameIsAtomic(t *testing.T) {
54 srv, st, _, _ := newTestServer(t)
55 dir := makeRepo(t, srv, st, "before", nil)
56 commitFiles(t, dir, "init", map[string]string{"a.txt": "x"})
57
58 sess := sessionCookie(t, login(t, srv, "alice", testPass))
59 csrf := csrfOf(t, srv, "/before/settings", sess)
60
61 form := url.Values{
62 "csrf": {csrf},
63 "new_name": {"after"},
64 "description": {"改过的描述"},
65 "default_branch": {"main"},
66 "ai_enabled": {"on"},
67 }
68 r := httptest.NewRequest(http.MethodPost, "/before/settings", strings.NewReader(form.Encode()))
69 r.Header.Set("Content-Type", "application/x-www-form-urlencoded")
70 r.AddCookie(&http.Cookie{Name: SessionCookieName, Value: sess})
71 w := httptest.NewRecorder()
72 srv.Handler().ServeHTTP(w, r)
73
74 if w.Code >= 400 {
75 t.Errorf("改名 + 保存设置返回 %d,应为 3xx(改名已生效,不该报错)", w.Code)
76 }
77 got, err := st.RepoByName("after")
78 if err != nil {
79 t.Fatalf("改名未生效: %v", err)
80 }
81 if got.Description != "改过的描述" {
82 t.Errorf("同一次提交里的描述没有保存: %q", got.Description)
83 }
84 if got.DefaultBranch != "main" {
85 t.Errorf("默认分支未保存: %q", got.DefaultBranch)
86 }
87}