85 lines
3.0 KiB
Go
85 lines
3.0 KiB
Go
package process
|
|
|
|
import (
|
|
"encoding/json"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// 1171/AC2: given an account file broker-<process id> in the controller's form {url, fingerprint, node,
|
|
// module, user, password, claims}, when the process package reads it, then it yields those fields and
|
|
// tolerates claims.
|
|
func TestReadAccountYieldsEveryFieldAndToleratesClaims(t *testing.T) {
|
|
path := writeAccount(t, map[string]any{
|
|
"url": "nats://novox:4222", "fingerprint": "sha256:ab", "node": "novox", "module": "mesh-mail",
|
|
"user": "novox.mesh-mail.send", "password": "secret-pw",
|
|
"claims": []map[string]any{{"seat": "operator-channel", "verbs": []string{"tell"}}},
|
|
})
|
|
a, err := ReadAccount(path)
|
|
if err != nil {
|
|
t.Fatalf("a well-formed account file was refused: %v", err)
|
|
}
|
|
if a.URL != "nats://novox:4222" || a.Fingerprint != "sha256:ab" || a.Node != "novox" ||
|
|
a.Module != "mesh-mail" || a.User != "novox.mesh-mail.send" || a.Password != "secret-pw" {
|
|
t.Fatalf("the account read back: %+v", a)
|
|
}
|
|
}
|
|
|
|
// 1171/AC2: a process account carries no claims at all (heldProcessAccount); reading it is not refused for
|
|
// the field being absent.
|
|
func TestReadAccountToleratesNoClaimsAtAll(t *testing.T) {
|
|
path := writeAccount(t, map[string]any{
|
|
"url": "nats://novox:4222", "node": "novox", "module": "mesh-mail",
|
|
"user": "novox.mesh-mail.send", "password": "secret-pw",
|
|
})
|
|
a, err := ReadAccount(path)
|
|
if err != nil {
|
|
t.Fatalf("a process account with no claims was refused: %v", err)
|
|
}
|
|
if a.User != "novox.mesh-mail.send" {
|
|
t.Fatalf("the account read back: %+v", a)
|
|
}
|
|
}
|
|
|
|
// 1171/AC2: a file missing url, user or password is refused, naming the field; the password never appears
|
|
// in the error even when it is the field present and another is missing.
|
|
func TestReadAccountRefusesAFileMissingAField(t *testing.T) {
|
|
for _, tc := range []struct {
|
|
field string
|
|
values map[string]any
|
|
}{
|
|
{"url", map[string]any{"node": "novox", "module": "mesh-mail", "user": "novox.mesh-mail.send", "password": "secret-pw"}},
|
|
{"user", map[string]any{"url": "nats://novox:4222", "node": "novox", "module": "mesh-mail", "password": "secret-pw"}},
|
|
{"password", map[string]any{"url": "nats://novox:4222", "node": "novox", "module": "mesh-mail", "user": "novox.mesh-mail.send"}},
|
|
} {
|
|
t.Run(tc.field, func(t *testing.T) {
|
|
path := writeAccount(t, tc.values)
|
|
_, err := ReadAccount(path)
|
|
if err == nil {
|
|
t.Fatalf("an account file missing %s was accepted", tc.field)
|
|
}
|
|
if !strings.Contains(err.Error(), tc.field) {
|
|
t.Errorf("the error %q does not name the missing field %s", err.Error(), tc.field)
|
|
}
|
|
if strings.Contains(err.Error(), "secret-pw") {
|
|
t.Errorf("the password appears in the error: %q", err.Error())
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func writeAccount(t *testing.T, fields map[string]any) string {
|
|
t.Helper()
|
|
b, err := json.Marshal(fields)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
path := filepath.Join(t.TempDir(), "broker-send")
|
|
if err := os.WriteFile(path, b, 0o600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return path
|
|
}
|