A game sold in the EU cannot ship what a licence excluding the EU made. On the profile page a person leaves out licences one by one, or by rule: every licence forbidding commercial use, every licence granting nothing in a region. The rules cover models added later. The choice reaches every principal through the resolved limits, so permits() leaves such models out of /v1/models, requests, jobs, fallbacks and the portal's pickers, and a request for one is refused 403 licence_excluded saying which choice did. Kept in user_excluded_licences (migration 0046), copied with the store and gone with the person. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
85 lines
2.8 KiB
Go
85 lines
2.8 KiB
Go
package web
|
|
|
|
import (
|
|
"log/slog"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"net/url"
|
|
"path/filepath"
|
|
"slices"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"gitea.mynodes.xyz/ilker/llmgw/internal/store"
|
|
)
|
|
|
|
func TestTheProfileKeepsTheLicencesAPersonLeavesOut(t *testing.T) {
|
|
ctx := t.Context()
|
|
st, err := store.OpenSQLite(ctx, filepath.Join(t.TempDir(), "l.db"))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer st.Close()
|
|
ada := store.User{ID: "usr-a", Email: "ada@example.com", State: store.UserActive, CreatedAt: time.Now()}
|
|
if err := st.CreateUser(ctx, ada); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
p := NewAccountPages(fakeAccounts{user: ada}, st, nil, "v0", slog.New(slog.DiscardHandler))
|
|
p.SetLicences(func() LicenceChoices {
|
|
return LicenceChoices{
|
|
Licences: []LicenceChoice{
|
|
{Key: "mit", Name: "MIT", Commercial: "yes", Models: []string{"triposr"}},
|
|
{Key: "tencent-hunyuan-community", Name: "Tencent Hunyuan Community",
|
|
ExcludedRegions: []string{"EU", "UK", "KR"}, Models: []string{"hunyuan3d"}},
|
|
},
|
|
Regions: []string{"EU", "KR", "UK"},
|
|
}
|
|
}, st)
|
|
mux := http.NewServeMux()
|
|
p.Register(mux)
|
|
do := func(method string, form url.Values) string {
|
|
var req *http.Request
|
|
if form == nil {
|
|
req = httptest.NewRequest(method, "/profile", nil)
|
|
} else {
|
|
form.Set("csrf", "tok")
|
|
req = httptest.NewRequest(method, "/profile/licences", strings.NewReader(form.Encode()))
|
|
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
|
}
|
|
req.AddCookie(&http.Cookie{Name: SessionCookie, Value: "good"})
|
|
req.AddCookie(&http.Cookie{Name: csrfCookie, Value: "tok"})
|
|
rec := httptest.NewRecorder()
|
|
mux.ServeHTTP(rec, req)
|
|
return rec.Body.String()
|
|
}
|
|
|
|
page := do(http.MethodGet, nil)
|
|
for _, want := range []string{`action="/profile/licences"`, "Tencent Hunyuan Community", "not in EU, UK, KR", "hunyuan3d"} {
|
|
if !strings.Contains(page, want) {
|
|
t.Errorf("the page lacks %q", want)
|
|
}
|
|
}
|
|
|
|
saved := do(http.MethodPost, url.Values{"region": {"EU"}, "regions_other": {"ch, NO"}, "licence": {"MIT"},
|
|
"non_commercial": {"1"}})
|
|
got, _ := st.UserExcludedLicences(ctx, ada.ID)
|
|
want := []string{"mit", "rule:non-commercial", "rule:region:CH", "rule:region:EU", "rule:region:NO"}
|
|
if !slices.Equal(got, want) || !strings.Contains(saved, "Saved.") {
|
|
t.Errorf("kept %v, want %v", got, want)
|
|
}
|
|
// What was kept is what the page shows ticked, a region no licence
|
|
// names yet included.
|
|
if !strings.Contains(saved, `value="CH" checked`) || !strings.Contains(saved, `value="mit" checked`) {
|
|
t.Error("the page does not show what was kept")
|
|
}
|
|
|
|
bad := do(http.MethodPost, url.Values{"regions_other": {"Europe"}})
|
|
if !strings.Contains(bad, "is not a region code") {
|
|
t.Error("a bad region was not refused")
|
|
}
|
|
if got2, _ := st.UserExcludedLicences(ctx, ada.ID); !slices.Equal(got2, want) {
|
|
t.Errorf("a refused form changed what was kept: %v", got2)
|
|
}
|
|
}
|