package kwallet import ( "context" "errors" "testing" "email-mcp/internal/secretstore" ) type walletClientStub struct { availableErr error openErr error writeErr error readErr error readValue []byte openCalled bool writeKey string writeValue []byte readKey string } func (c *walletClientStub) IsAvailable(context.Context) error { return c.availableErr } func (c *walletClientStub) Open(context.Context) error { c.openCalled = true return c.openErr } func (c *walletClientStub) WriteEntry(_ context.Context, key string, value []byte) error { c.writeKey = key c.writeValue = value return c.writeErr } func (c *walletClientStub) ReadEntry(_ context.Context, key string) ([]byte, error) { c.readKey = key return c.readValue, c.readErr } func TestStoreSaveWritesSerializedCredential(t *testing.T) { client := &walletClientStub{} store := NewStore(client) cred := secretstore.Credential{ Host: "imap.example.com", Username: "alice", Password: "secret", } if err := store.Save(context.Background(), secretstore.DefaultAccountKey, cred); err != nil { t.Fatalf("Save returned error: %v", err) } if !client.openCalled { t.Fatal("expected wallet Open to be called") } if client.writeKey != secretstore.DefaultAccountKey { t.Fatalf("unexpected key: %s", client.writeKey) } if len(client.writeValue) == 0 { t.Fatal("expected serialized credential payload") } } func TestStoreSaveReturnsAvailabilityErrorWithoutOpeningWallet(t *testing.T) { wantErr := errors.New("kwallet unavailable") client := &walletClientStub{availableErr: wantErr} store := NewStore(client) err := store.Save(context.Background(), secretstore.DefaultAccountKey, secretstore.Credential{ Host: "imap.example.com", Username: "alice", Password: "secret", }) if !errors.Is(err, wantErr) { t.Fatalf("expected availability error, got %v", err) } if client.openCalled { t.Fatal("did not expect wallet Open when availability check fails") } } func TestStoreLoadReadsAndDecodesCredential(t *testing.T) { payload, err := secretstore.MarshalCredential(secretstore.Credential{ Host: "imap.example.com", Username: "alice", Password: "secret", }) if err != nil { t.Fatalf("MarshalCredential returned error: %v", err) } client := &walletClientStub{readValue: payload} store := NewStore(client) cred, err := store.Load(context.Background(), secretstore.DefaultAccountKey) if err != nil { t.Fatalf("Load returned error: %v", err) } if !client.openCalled { t.Fatal("expected wallet Open to be called") } if client.readKey != secretstore.DefaultAccountKey { t.Fatalf("unexpected key: %s", client.readKey) } if cred.Host != "imap.example.com" || cred.Username != "alice" || cred.Password != "secret" { t.Fatalf("unexpected credential: %#v", cred) } }