test(api): own password-change fixture router lifecycle

Register shared router cleanup at the password-change constructor boundary so workers are cancelled and joined before temporary state is removed. Add a subtest-boundary regression that fails without cleanup and retain the three affected authorisation tests. No production behaviour or qualification threshold changes.

Change-source: pulse-maintainer
This commit is contained in:
pulse-triage[bot] 2026-09-08 21:53:18 +01:00
parent d242055f98
commit 63f9bdcbbe

View file

@ -23,7 +23,9 @@ func newChangePasswordRouter(t *testing.T) (*Router, *config.Config) {
t.Fatalf("bcrypt: %v", err)
}
cfg := &config.Config{DataPath: dir, ConfigPath: dir, AuthUser: "admin", AuthPass: string(hashed)}
return NewRouter(cfg, nil, nil, nil, nil, "1.0.0"), cfg
router := NewRouter(cfg, nil, nil, nil, nil, "1.0.0")
cleanupTestRouter(t, router)
return router, cfg
}
func changePasswordRequest(t *testing.T, current string) *http.Request {
@ -87,3 +89,27 @@ func TestChangePasswordBasicAuthPathUnaffected(t *testing.T) {
t.Fatalf("Basic Auth change-password must not be refused by the session gate, got 403 (body %s)", rec.Body.String())
}
}
func TestChangePasswordFixtureOwnsRouterLifecycle(t *testing.T) {
var router *Router
workerDone := make(chan struct{})
t.Run("fixture", func(t *testing.T) {
router, _ = newChangePasswordRouter(t)
router.startLifecycleWorker(func() {
<-router.lifecycleCtx.Done()
close(workerDone)
})
})
// Ensure a failing regression does not itself leave workers running.
cleanupTestRouter(t, router)
select {
case <-router.lifecycleCtx.Done():
default:
t.Fatal("password-change fixture left router lifecycle active")
}
select {
case <-workerDone:
default:
t.Fatal("password-change fixture did not join its router worker")
}
}