package process import ( "encoding/json" "os" "path/filepath" "strings" "testing" ) // 1171/AC2: given an account file broker- 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 }