185f4f578e
- New credentials_test.go: 4 test functions covering credentialStore (new, save, lookup, update, persistence across restarts). - Extended handlers_test.go: fakeCore now supports WriteFact, Presence, RecentFacts/Nudges/Notes, RevertFact. Added 7 new test functions: TestNoCache, TestHandleSignal (5 subtestcases covering method guard, nil core, unknown key, known key, write error), TestHandleDash (3), TestHandleHistory (3), TestHandleRevert (6), and ListToolsError 502. - Fixed history.html: Go html/template requires conditional class rendered as separate <tr> branches, not inline attribute.
189 lines
4.8 KiB
Go
189 lines
4.8 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
)
|
|
|
|
func TestNewCredentialStore(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
t.Run("non-existent path returns empty store", func(t *testing.T) {
|
|
cs, err := newCredentialStore(filepath.Join(t.TempDir(), "nonexistent.json"))
|
|
if err != nil {
|
|
t.Fatalf("newCredentialStore(nonexistent) = _, %v, want nil", err)
|
|
}
|
|
if cs == nil {
|
|
t.Fatal("newCredentialStore returned nil store")
|
|
}
|
|
})
|
|
|
|
t.Run("valid JSON loads credentials", func(t *testing.T) {
|
|
path := filepath.Join(t.TempDir(), "creds.json")
|
|
creds := map[string]localCred{
|
|
"cred1": {PublicKey: []byte("key1"), SignCount: 5},
|
|
}
|
|
data, _ := json.Marshal(creds)
|
|
os.WriteFile(path, data, 0600)
|
|
|
|
cs, err := newCredentialStore(path)
|
|
if err != nil {
|
|
t.Fatalf("newCredentialStore(valid) = _, %v, want nil", err)
|
|
}
|
|
pk, sc, err := cs.Lookup("cred1")
|
|
if err != nil {
|
|
t.Fatalf("Lookup cred1: %v", err)
|
|
}
|
|
if string(pk) != "key1" {
|
|
t.Errorf("publicKey = %q, want %q", string(pk), "key1")
|
|
}
|
|
if sc != 5 {
|
|
t.Errorf("signCount = %d, want 5", sc)
|
|
}
|
|
})
|
|
|
|
t.Run("invalid JSON returns parse error", func(t *testing.T) {
|
|
path := filepath.Join(t.TempDir(), "bad.json")
|
|
os.WriteFile(path, []byte("{invalid"), 0600)
|
|
|
|
_, err := newCredentialStore(path)
|
|
if err == nil {
|
|
t.Fatal("newCredentialStore(invalid JSON) = _, nil, want error")
|
|
}
|
|
})
|
|
|
|
t.Run("empty file returns empty store", func(t *testing.T) {
|
|
path := filepath.Join(t.TempDir(), "empty.json")
|
|
os.WriteFile(path, nil, 0600)
|
|
|
|
cs, err := newCredentialStore(path)
|
|
if err != nil {
|
|
t.Fatalf("newCredentialStore(empty) = _, %v, want nil", err)
|
|
}
|
|
_, _, err = cs.Lookup("anything")
|
|
if err == nil {
|
|
t.Fatal("Lookup anything on empty store: expected error")
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestCredentialStoreSaveAndLookup(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
t.Run("save then lookup returns credential with signCount=0", func(t *testing.T) {
|
|
path := filepath.Join(t.TempDir(), "creds.json")
|
|
cs, err := newCredentialStore(path)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
err = cs.Save("mykey", []byte("pubkey-data"))
|
|
if err != nil {
|
|
t.Fatalf("Save: %v", err)
|
|
}
|
|
|
|
pk, sc, err := cs.Lookup("mykey")
|
|
if err != nil {
|
|
t.Fatalf("Lookup mykey: %v", err)
|
|
}
|
|
if string(pk) != "pubkey-data" {
|
|
t.Errorf("publicKey = %q, want %q", string(pk), "pubkey-data")
|
|
}
|
|
if sc != 0 {
|
|
t.Errorf("signCount = %d, want 0", sc)
|
|
}
|
|
})
|
|
|
|
t.Run("save duplicate ID returns error", func(t *testing.T) {
|
|
path := filepath.Join(t.TempDir(), "creds.json")
|
|
cs, _ := newCredentialStore(path)
|
|
cs.Save("dup", []byte("first"))
|
|
err := cs.Save("dup", []byte("second"))
|
|
if err == nil {
|
|
t.Fatal("Save duplicate: expected error")
|
|
}
|
|
})
|
|
|
|
t.Run("lookup non-existent ID returns error", func(t *testing.T) {
|
|
path := filepath.Join(t.TempDir(), "creds.json")
|
|
cs, _ := newCredentialStore(path)
|
|
_, _, err := cs.Lookup("nobody")
|
|
if err == nil {
|
|
t.Fatal("Lookup non-existent: expected error")
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestCredentialStoreUpdateSignCount(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
t.Run("save, update, then lookup returns new count", func(t *testing.T) {
|
|
path := filepath.Join(t.TempDir(), "creds.json")
|
|
cs, _ := newCredentialStore(path)
|
|
cs.Save("ctr", []byte("pk"))
|
|
|
|
err := cs.UpdateSignCount("ctr", 42)
|
|
if err != nil {
|
|
t.Fatalf("UpdateSignCount: %v", err)
|
|
}
|
|
|
|
_, sc, err := cs.Lookup("ctr")
|
|
if err != nil {
|
|
t.Fatalf("Lookup after update: %v", err)
|
|
}
|
|
if sc != 42 {
|
|
t.Errorf("signCount = %d, want 42", sc)
|
|
}
|
|
})
|
|
|
|
t.Run("update non-existent credential returns error", func(t *testing.T) {
|
|
path := filepath.Join(t.TempDir(), "creds.json")
|
|
cs, _ := newCredentialStore(path)
|
|
err := cs.UpdateSignCount("ghost", 1)
|
|
if err == nil {
|
|
t.Fatal("UpdateSignCount non-existent: expected error")
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestCredentialStorePersistence(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
t.Run("credential persists across store instances", func(t *testing.T) {
|
|
path := filepath.Join(t.TempDir(), "persist.json")
|
|
cs, _ := newCredentialStore(path)
|
|
cs.Save("persist-key", []byte("persist-data"))
|
|
|
|
cs2, err := newCredentialStore(path)
|
|
if err != nil {
|
|
t.Fatalf("newCredentialStore(reopen): %v", err)
|
|
}
|
|
pk, _, err := cs2.Lookup("persist-key")
|
|
if err != nil {
|
|
t.Fatalf("Lookup persist-key after reopen: %v", err)
|
|
}
|
|
if string(pk) != "persist-data" {
|
|
t.Errorf("publicKey = %q, want %q", string(pk), "persist-data")
|
|
}
|
|
})
|
|
|
|
t.Run("file deleted results in empty store", func(t *testing.T) {
|
|
path := filepath.Join(t.TempDir(), "deleted.json")
|
|
cs, _ := newCredentialStore(path)
|
|
cs.Save("gone-key", []byte("gone-data"))
|
|
|
|
os.Remove(path)
|
|
|
|
cs2, err := newCredentialStore(path)
|
|
if err != nil {
|
|
t.Fatalf("newCredentialStore(after delete): %v", err)
|
|
}
|
|
_, _, err = cs2.Lookup("gone-key")
|
|
if err == nil {
|
|
t.Fatal("Lookup gone-key after file delete: expected error")
|
|
}
|
|
})
|
|
}
|