One name per thing, per the HQ glossary: the module/container/image/binary/repo becomes mesh-controller, the seat the-controller, and the store+broker pair the foundation (embedded base bundles, default template and example lock renamed with their go:embed directives). No behaviour change — a pure vocabulary rename. Claude-Session: https://claude.ai/code/session_01D6qtiYU3P9jk3pnAXyAFyx
78 lines
2.9 KiB
Go
78 lines
2.9 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
type letIn struct{}
|
|
|
|
func (letIn) Who(*http.Request) (string, error) { return "somebody", nil }
|
|
|
|
func asking(t *testing.T, who Authenticator, method, path, body string) *httptest.ResponseRecorder {
|
|
t.Helper()
|
|
recorded := httptest.NewRecorder()
|
|
commands(who).ServeHTTP(recorded, httptest.NewRequest(method, path, strings.NewReader(body)))
|
|
return recorded
|
|
}
|
|
|
|
// **Nothing is served to somebody the mesh cannot identify**, and that is the default rather than
|
|
// a setting. The board this stands behind is published on a public name (novox/hq 11-a-board), so
|
|
// an unauthenticated command surface is authority over the mesh handed to whoever finds it.
|
|
func TestAnUnauthenticatedRequestIsRefused(t *testing.T) {
|
|
got := asking(t, mustAuthenticate("https://identity.example/realms/mesh"),
|
|
"POST", "/assign", `{"node":"anchor","module":"umami"}`)
|
|
if got.Code != http.StatusUnauthorized {
|
|
t.Fatalf("an unidentified caller got %d", got.Code)
|
|
}
|
|
// And it says what to do instead, because the answer is not "give up".
|
|
if !strings.Contains(got.Body.String(), "command line") {
|
|
t.Errorf("the refusal does not say what still works: %s", got.Body.String())
|
|
}
|
|
}
|
|
|
|
// The API refuses to start at all without being told whose tokens to believe.
|
|
//
|
|
// At start rather than per request, so it is found by whoever ran it rather than by whoever
|
|
// finds it.
|
|
func TestTheApiWillNotRunWithoutAnIssuer(t *testing.T) {
|
|
err := apiCommand(context.Background(), []string{})
|
|
if err == nil {
|
|
t.Fatal("it served commands without being told who may give them")
|
|
}
|
|
if !strings.Contains(err.Error(), "issuer") {
|
|
t.Errorf("the refusal does not name what is missing: %v", err)
|
|
}
|
|
}
|
|
|
|
// A request missing what it acts on is refused before anything is opened.
|
|
func TestARequestThatNamesNothingIsRefused(t *testing.T) {
|
|
// **The exact refusal, not merely "not accepted".** Asserting non-200 passes even when the
|
|
// request got as far as opening a store and failing there, which proves nothing about whether
|
|
// anything was checked — that is what the first version of this test did.
|
|
for _, body := range []string{`{}`, `{"node":"anchor"}`, `{"module":"umami"}`, `not json`} {
|
|
got := asking(t, letIn{}, "POST", "/assign", body)
|
|
if got.Code != http.StatusBadRequest {
|
|
t.Errorf("%s got %d, and a request naming nothing is a bad request", body, got.Code)
|
|
}
|
|
}
|
|
}
|
|
|
|
// A verb nobody implemented is said plainly. A command surface answering 404 to something
|
|
// somebody expected is indistinguishable from one that is down.
|
|
func TestAnUnknownRouteSaysWhatIsAccepted(t *testing.T) {
|
|
got := asking(t, letIn{}, "POST", "/rotate", `{}`)
|
|
if got.Code != http.StatusNotFound {
|
|
t.Fatalf("got %d", got.Code)
|
|
}
|
|
var said map[string]any
|
|
_ = json.Unmarshal(got.Body.Bytes(), &said)
|
|
if !strings.Contains(said["refused"].(string), "/assign") {
|
|
t.Errorf("it does not say what it does accept: %v", said)
|
|
}
|
|
}
|