feat(mail): IMAP client — select, fetch headers/full, search
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
//go:build integration
|
||||
|
||||
package mail
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strconv"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// These tests require a GreenMail server reachable via env vars:
|
||||
//
|
||||
// EMCLI_TEST_IMAP_HOST, EMCLI_TEST_IMAP_PORT, EMCLI_TEST_USER, EMCLI_TEST_PASS
|
||||
//
|
||||
// Run: go test -tags=integration ./internal/mail/
|
||||
func testCfg(t *testing.T) IMAPConfig {
|
||||
t.Helper()
|
||||
host := os.Getenv("EMCLI_TEST_IMAP_HOST")
|
||||
if host == "" {
|
||||
t.Skip("EMCLI_TEST_IMAP_HOST not set; skipping IMAP integration test")
|
||||
}
|
||||
return IMAPConfig{
|
||||
Host: host,
|
||||
Port: atoiEnv(t, "EMCLI_TEST_IMAP_PORT"),
|
||||
Security: "starttls",
|
||||
Username: os.Getenv("EMCLI_TEST_USER"),
|
||||
Password: os.Getenv("EMCLI_TEST_PASS"),
|
||||
}
|
||||
}
|
||||
|
||||
func TestSelectAndFetch(t *testing.T) {
|
||||
c, err := Dial(testCfg(t))
|
||||
if err != nil {
|
||||
t.Fatalf("Dial: %v", err)
|
||||
}
|
||||
defer c.Logout()
|
||||
|
||||
uidv, maxUID, err := c.SelectFolder("INBOX")
|
||||
if err != nil {
|
||||
t.Fatalf("SelectFolder: %v", err)
|
||||
}
|
||||
if uidv == 0 {
|
||||
t.Fatal("uidvalidity should be non-zero")
|
||||
}
|
||||
headers, err := c.FetchHeaders("INBOX", nil)
|
||||
if err != nil {
|
||||
t.Fatalf("FetchHeaders: %v", err)
|
||||
}
|
||||
t.Logf("inbox has %d messages, maxUID=%d", len(headers), maxUID)
|
||||
}
|
||||
|
||||
func atoiEnv(t *testing.T, k string) int {
|
||||
t.Helper()
|
||||
n, err := strconv.Atoi(os.Getenv(k))
|
||||
if err != nil {
|
||||
t.Fatalf("bad int env %s: %v", k, err)
|
||||
}
|
||||
return n
|
||||
}
|
||||
Reference in New Issue
Block a user