fix templates v2

This commit is contained in:
tamakyi
2026-10-22 17:49:25 +08:00
parent bd02eb7ed2
commit b939d26ff0
11 changed files with 436 additions and 60 deletions
+56
View File
@@ -0,0 +1,56 @@
package question
import (
"net/http/httptest"
"testing"
"github.com/flamego/flamego"
"github.com/flamego/template"
"github.com/tamakyi/TamaBox/internal/context"
)
// 从后台进入单题页时的筛选参数会写进表单 action 的 query,POST 回来要靠
// from=admin 重新认出来源。丢了它,「回答并下一条」/「下一条未读」跳转后
// 页脚「返回」会掉回箱主页(实测过)。
func TestAdminBackQueryKeepsFrom(t *testing.T) {
cases := []struct {
name string
url string
want string
}{
{"非后台来源", "/answer?sort=new", ""},
{"后台来源无筛选", "/answer?from=admin", "from=admin"},
{"后台来源带筛选", "/answer?from=admin&sort=new&read=2", "from=admin&read=2&sort=new"},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
var got string
f := flamego.New()
f.Post("/answer", func(fc flamego.Context) {
ctx := context.Context{Context: fc, Data: template.Data{}}
got = adminBackQuery(ctx)
})
f.ServeHTTP(httptest.NewRecorder(), httptest.NewRequest("POST", c.url, nil))
if got != c.want {
t.Fatalf("adminBackQuery(%q) = %q, want %q", c.url, got, c.want)
}
})
}
}
// 跳转地址必须带回完整的后台上下文,否则下一条页面认不出来源。
func TestQuestionPathKeepsAdminContext(t *testing.T) {
var got string
f := flamego.New()
f.Post("/next-unread", func(fc flamego.Context) {
ctx := context.Context{Context: fc, Data: template.Data{}}
got = questionPath(ctx, "box", 7)
})
f.ServeHTTP(httptest.NewRecorder(), httptest.NewRequest("POST", "/next-unread?from=admin&sort=new", nil))
want := "/_/box/7?from=admin&sort=new"
if got != want {
t.Fatalf("questionPath() = %q, want %q", got, want)
}
}
+6 -2
View File
@@ -276,7 +276,7 @@ func PublishAnswer(ctx context.Context, pageUser *db.User, question *db.Question
return
}
}
ctx.Redirect(fmt.Sprintf("/_/%s/%d", pageUser.Domain, question.ID))
ctx.Redirect(questionPath(ctx, pageUser.Domain, question.ID))
}
func Delete(ctx context.Context, pageUser *db.User, question *db.Question, canDelete bool) {
@@ -459,12 +459,16 @@ func questionPath(ctx context.Context, domain string, questionID uint) string {
// adminBackQuery 提取后台列表的筛选参数(仅 from=admin 时有效),供单题页的
// 「返回」「下一条未读」沿用。POST 请求从表单 action 的 query 里读取。
// 返回值始终带 from=admin:调用方会把它重新写进表单 action 与跳转地址,
// 少一个 from,下一次 POST 就认不出来源了。
func adminBackQuery(ctx context.Context) string {
if ctx.Query("from") != "admin" {
return ""
}
backQuery := url.Values{}
// from 必须随表单 action 回到 POST:ctx.Query 只读 URL query,
// 少了它就认不出来源,「返回」会掉回箱主页。
backQuery := url.Values{"from": {"admin"}}
for _, key := range []string{"sort", "status", "type", "read", "q"} {
if v := ctx.Query(key); v != "" {
backQuery.Set(key, v)