hub v0.15.0: Phase 2 managed updates — per-customer controller-version floor
Operator sets a minimum controller version (FLOOR), per-customer defaulting to a
global floor; the report ACK returns the effective floor + latest_version so the
controller auto-updates to the floor when below it (latest stays the opt-in button).
- store: min_controller_version column + hub_settings global floor + Effective/
Get/SetGlobal/SetMin resolution + config/env DEFAULT_MIN_CONTROLLER_VERSION
- handler: report ACK {min_controller_version, latest_version}; LatestVersionProvider
- web: global floor editor + per-customer override form + Floor column (English)
- tests: floor resolution + ACK + render; override-precedence red-proof verified
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FSZmmSFVzGwEzhYmxbkgBK
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
package web
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"log"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"gitea.dooplex.hu/admin/felhom-hub/internal/store"
|
||||
)
|
||||
|
||||
// Catches template SYNTAX errors (template.Must in New panics) and that the floor fields render on the
|
||||
// two edited pages. Field-level execution errors surface as a non-nil ExecuteTemplate error.
|
||||
func TestTemplates_FloorRender(t *testing.T) {
|
||||
st, err := store.New(filepath.Join(t.TempDir(), "t.db"), log.New(io.Discard, "", 0))
|
||||
if err != nil {
|
||||
t.Fatalf("store.New: %v", err)
|
||||
}
|
||||
t.Cleanup(func() { st.Close() })
|
||||
s := New(st, "", "", "test", time.Hour, log.New(io.Discard, "", 0)) // template.Must runs here
|
||||
|
||||
// configs.html — the list page data shape used by handleConfigList.
|
||||
cfgData := struct {
|
||||
Customers []customerListEntry
|
||||
GlobalFloor string
|
||||
ActiveNav string
|
||||
Flash string
|
||||
CSRFToken string
|
||||
CSRFField string
|
||||
}{
|
||||
Customers: []customerListEntry{{
|
||||
CustomerID: "c", EffectiveFloor: "0.87.0", FloorOverride: "0.87.0", BelowFloor: true,
|
||||
ControllerVersion: "0.86.0", HasConfig: true,
|
||||
}},
|
||||
GlobalFloor: "0.86.0",
|
||||
ActiveNav: "configs",
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
if err := s.templates.ExecuteTemplate(&buf, "configs.html", cfgData); err != nil {
|
||||
t.Fatalf("render configs.html: %v", err)
|
||||
}
|
||||
if !bytes.Contains(buf.Bytes(), []byte("0.87.0")) || !bytes.Contains(buf.Bytes(), []byte("global floor")) {
|
||||
t.Errorf("configs.html missing floor content")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user