email-mcp/internal/cli/integration_test.go

86 lines
2.5 KiB
Go
Raw Normal View History

2026-04-10 10:35:08 +00:00
package cli
import (
"bytes"
"context"
"testing"
"email-mcp/internal/imapclient"
"email-mcp/internal/mcpserver"
"email-mcp/internal/secretstore"
"email-mcp/internal/secretstore/kwallet"
)
2026-04-10 10:39:10 +00:00
type entrypointPromptStub struct {
2026-04-10 10:35:08 +00:00
credential secretstore.Credential
}
2026-04-10 10:39:10 +00:00
func (p *entrypointPromptStub) PromptSetup(context.Context) (secretstore.Credential, error) {
2026-04-10 10:35:08 +00:00
return p.credential, nil
}
2026-04-10 10:39:10 +00:00
type entrypointStoreStub struct {
saveErr error
loadErr error
2026-04-10 10:35:08 +00:00
}
2026-04-10 10:39:10 +00:00
func (s *entrypointStoreStub) Save(context.Context, string, secretstore.Credential) error {
return s.saveErr
2026-04-10 10:35:08 +00:00
}
2026-04-10 10:39:10 +00:00
func (s *entrypointStoreStub) Load(context.Context, string) (secretstore.Credential, error) {
return secretstore.Credential{}, s.loadErr
2026-04-10 10:35:08 +00:00
}
2026-04-10 10:39:10 +00:00
type entrypointMailServiceStub struct{}
2026-04-10 10:35:08 +00:00
2026-04-10 10:39:10 +00:00
func (entrypointMailServiceStub) ListMailboxes(context.Context, secretstore.Credential) ([]imapclient.Mailbox, error) {
2026-04-10 10:35:08 +00:00
return nil, nil
}
2026-04-10 10:39:10 +00:00
func (entrypointMailServiceStub) ListMessages(context.Context, secretstore.Credential, string, int) ([]imapclient.MessageSummary, error) {
2026-04-10 10:35:08 +00:00
return nil, nil
}
2026-04-10 10:39:10 +00:00
func (entrypointMailServiceStub) GetMessage(context.Context, secretstore.Credential, string, uint32) (imapclient.Message, error) {
2026-04-10 10:35:08 +00:00
return imapclient.Message{}, nil
}
2026-04-10 10:39:10 +00:00
func TestExecuteSetupWritesWalletGuidanceAndReturnsExitCodeOne(t *testing.T) {
app := NewAppWithDependencies(
&entrypointPromptStub{
credential: secretstore.Credential{
Host: "imap.example.com",
Username: "alice",
Password: "secret",
},
2026-04-10 10:35:08 +00:00
},
2026-04-10 10:39:10 +00:00
&entrypointStoreStub{saveErr: kwallet.ErrKWalletUnavailable},
nil,
nil,
)
stderr := &bytes.Buffer{}
if code := Execute(app, []string{"setup"}, stderr); code != 1 {
t.Fatalf("expected exit code 1, got %d", code)
2026-04-10 10:35:08 +00:00
}
2026-04-10 10:39:10 +00:00
if got := stderr.String(); got != "kwallet is not available; make sure KDE Wallet is installed and your session D-Bus is running\n" {
t.Fatalf("unexpected stderr: %q", got)
2026-04-10 10:35:08 +00:00
}
}
2026-04-10 10:39:10 +00:00
func TestExecuteMCPWritesMissingCredentialGuidanceAndReturnsExitCodeOne(t *testing.T) {
store := &entrypointStoreStub{loadErr: kwallet.ErrCredentialNotFound}
mail := entrypointMailServiceStub{}
runner := mcpserver.NewRunner(mcpserver.New(store, mail), nil, &bytes.Buffer{}, &bytes.Buffer{})
app := NewAppWithDependencies(nil, store, runner, nil)
2026-04-10 10:35:08 +00:00
2026-04-10 10:39:10 +00:00
stderr := &bytes.Buffer{}
if code := Execute(app, []string{"mcp"}, stderr); code != 1 {
t.Fatalf("expected exit code 1, got %d", code)
2026-04-10 10:35:08 +00:00
}
2026-04-10 10:39:10 +00:00
if got := stderr.String(); got != "credentials not configured; run `email-mcp setup`\n" {
t.Fatalf("unexpected stderr: %q", got)
2026-04-10 10:35:08 +00:00
}
}