package templates import ( "strings" "testing" "time" ) // 从后台进入单题页时,表单 action 必须原样带上筛选参数。 // 回归点:曾经写成 action="...?{{ .NextQuery }}",html/template 会把查询片段整体编码, // = 和 & 变成 %3d / %26,服务端解析不出 from,跳转后「返回」掉回箱主页(线上实测过)。 func TestOwnerFormsKeepAdminQuery(t *testing.T) { data := publicBaseData() data["CanDelete"] = true data["IsOwnPage"] = true data["NextUnreadID"] = uint(2) data["BackFrom"] = "admin" data["BackTo"] = "/user/questions?from=admin&sort=new" data["AnswerAction"] = "/_/tester/1/answer?from=admin&sort=new" data["NextUnreadAction"] = "/_/tester/1/next-unread?from=admin&sort=new" data["Question"] = map[string]interface{}{ "ID": 1, "Content": "测试提问", "Answer": "", "CreatedAt": time.Now(), "UpdatedAt": time.Now(), "IsPrivate": false, "IsPinned": false, "IsRead": false, "Token": "abc123", "ReceiveReplyEmail": "", } data["QuestionToken"] = "abc123" data["AskUploadImages"] = []interface{}{} data["AnswerUploadImages"] = []interface{}{} data["FollowUps"] = []interface{}{} data["CanFollowUp"] = false data["IsQuestioner"] = false out, err := renderToString(t, "question/item", data) if err != nil { t.Fatalf("render question/item: %v", err) } for _, want := range []string{ `action="/_/tester/1/answer?from=admin&sort=new"`, `action="/_/tester/1/next-unread?from=admin&sort=new"`, `href="/user/questions?from=admin&sort=new"`, } { if !strings.Contains(out, want) { t.Fatalf("渲染结果缺少 %s", want) } } if strings.Contains(strings.ToLower(out), "%3d") || strings.Contains(out, "%26") { t.Fatal("action 里的 = / & 被 percent-encode 了,服务端会解析不出 from=admin") } }