test(14.2.1-04): add ML, markdown, resolver, and SPA test matrices

Prove nested ML writes, unsafe markdown rejection, request-locale isolation, and generated FormView types.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Jakub Zych
2026-10-06 14:02:49 +02:00
parent c7e2e4b4ed
commit 1bc6200dbd
5 changed files with 447 additions and 0 deletions

View File

@@ -1,8 +1,11 @@
package surf
import (
"context"
"fmt"
"net/http"
"net/http/httptest"
"sync"
"testing"
"git.golem15.com/golem15/summercms/modules/backpack"
@@ -59,6 +62,93 @@ func TestLocaleResolverWritesValidatedCodeAndStripsPrefix(t *testing.T) {
}
}
func TestLocaleResolver(t *testing.T) {
t.Run("present writes validated code", TestLocaleResolverWritesValidatedCodeAndStripsPrefix)
t.Run("absent keeps Accept-Language", TestLocaleAbsentResolverKeepsAcceptLanguage)
t.Run("conflicting requests stay isolated", TestLocaleResolverRequestIsolation)
}
func TestLocaleResolverRequestIsolation(t *testing.T) {
cfg := writeHTTPConfig(t, "body_limits:\n default_bytes: 1024\n upload_bytes: 1024\n")
app := backpack.New(cfg)
if err := app.Publish[LocaleResolver](pathLocaleResolver{}); err != nil {
t.Fatal(err)
}
r := New(nil)
r.app = app
r.defaultBytes = 1024
r.BindPlugin("acme.blog")
var mu sync.Mutex
got := map[string]string{}
r.Get("/posts", func(w http.ResponseWriter, req *http.Request) {
code, _ := towel.Locale(req.Context())
mu.Lock()
got[req.Header.Get("X-Req")] = code
mu.Unlock()
w.WriteHeader(http.StatusNoContent)
})
h, err := r.compile()
if err != nil {
t.Fatal(err)
}
var wg sync.WaitGroup
for i, code := range []string{"pl", "en", "pl", "en"} {
wg.Add(1)
go func(i int, code string) {
defer wg.Done()
id := fmt.Sprintf("%s-%d", code, i)
req := httptest.NewRequest(http.MethodGet, "/"+code+"/posts", nil)
req.Header.Set("X-Req", id)
req.Header.Set("Accept-Language", "de")
h.ServeHTTP(httptest.NewRecorder(), req)
mu.Lock()
if got[id] != code {
t.Errorf("request %s locale = %q", id, got[id])
}
mu.Unlock()
}(i, code)
}
wg.Wait()
}
type pathLocaleResolver struct{}
func (pathLocaleResolver) Resolve(_ http.ResponseWriter, r *http.Request) string {
if r == nil {
return "en"
}
if v := r.Context().Value(stubPrefixKey{}); v != nil {
if code, ok := v.(string); ok && code != "" {
return code
}
}
path := r.URL.Path
if len(path) >= 3 && path[0] == '/' && (path[1:3] == "pl" || path[1:3] == "en") {
return path[1:3]
}
return "en"
}
func (pathLocaleResolver) Rewrite(r *http.Request) *http.Request {
if r == nil {
return r
}
path := r.URL.Path
if len(path) >= 3 && path[0] == '/' && (path[1:3] == "pl" || path[1:3] == "en") && (len(path) == 3 || path[3] == '/') {
code := path[1:3]
clone := r.Clone(context.WithValue(r.Context(), stubPrefixKey{}, code))
if len(path) == 3 {
clone.URL.Path = "/"
} else {
clone.URL.Path = path[3:]
}
return clone
}
return r
}
type stubPrefixKey struct{}
func TestLocaleAbsentResolverKeepsAcceptLanguage(t *testing.T) {
r := New(nil)
r.BindPlugin("acme.blog")