// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Commercial
// SPDX-FileCopyrightText: 2025-2026 Christian Galo
package server
// Render tests for the two form parts themselves (spec form-library "The
// form part owns the container"; spec form-conventions). They execute
// ui_form.html and ui_form_field.html against forms.Render's view, so the
// markup every migrated form will produce is pinned once, here, rather
// than re-asserted per form. No DB needed.
import (
"bytes"
"html/template"
"io/fs"
"strings"
"testing"
"git.coopcloud.tech/wiki-cafe/member-console/internal/embeds"
"git.coopcloud.tech/wiki-cafe/member-console/internal/forms"
"git.coopcloud.tech/wiki-cafe/member-console/internal/web"
)
// renderFormPart executes the form part against one rendered declaration.
func renderFormPart(t *testing.T, view forms.FormView) string {
t.Helper()
tmpl := template.New("parts").Funcs(template.FuncMap{"helpIcon": helpIcon})
tmpl, err := web.ParseUIPartials(tmpl)
if err != nil {
t.Fatalf("ParseUIPartials: %v", err)
}
if _, err := fs.Sub(embeds.Templates, "templates"); err != nil {
t.Fatalf("fs.Sub: %v", err)
}
var buf bytes.Buffer
if err := tmpl.ExecuteTemplate(&buf, "form", view); err != nil {
t.Fatalf("execute the form part: %v", err)
}
return buf.String()
}
// A checkbox renders as Bootstrap's form-check with the label after the
// box, because the label names the state the box turns on, and the help
// icon after the label as its sibling, never inside it (findings FA-37,
// FA-50).
func TestFormPartCheckboxLabelSitsAfterTheBox(t *testing.T) {
spec := forms.FormSpec{
Name: "test.checkbox", Kind: forms.KindEdit, Family: forms.Stacked,
Method: "PUT", Path: "/partials/test", Commit: "Save",
Fields: []forms.Field{{
Name: "visibility", Label: "Listed", Control: forms.Checkbox, Value: "public",
Help: forms.Help("Listed", "Shown in the member catalog."),
}},
}
out := renderFormPart(t, forms.Render(spec, forms.Binding{Mode: forms.ModeUnbound}))
box := strings.Index(out, `type="checkbox"`)
label := strings.Index(out, `class="form-check-label"`)
help := strings.Index(out, `aria-label="Help: Listed"`)
if box < 0 || label < 0 || help < 0 {
t.Fatalf("checkbox, label or help icon missing:\n%s", out)
}
if !(box < label && label < help) {
t.Errorf("expected the order box, label, help icon; got %d, %d, %d:\n%s", box, label, help, out)
}
if !strings.Contains(out, `
`) {
t.Errorf("expected Bootstrap's form-check wrapper:\n%s", out)
}
// The help icon is the label's sibling: no button inside the label.
if strings.Contains(out, `