package mail import ( "bufio" "context" "net" "strings" "testing" ) // relay is the least of an SMTP server: it takes one message and keeps it. func relay(t *testing.T) (addr string, got chan string) { t.Helper() ln, err := net.Listen("tcp", "127.0.0.1:0") if err != nil { t.Fatal(err) } got = make(chan string, 1) go func() { c, err := ln.Accept() if err != nil { return } defer c.Close() r := bufio.NewReader(c) say := func(s string) { _, _ = c.Write([]byte(s + "\r\n")) } say("220 relay ready") var data strings.Builder inData := false for { line, err := r.ReadString('\n') if err != nil { return } if inData { if line == ".\r\n" { inData = false got <- data.String() say("250 kept") continue } data.WriteString(line) continue } switch cmd := strings.ToUpper(strings.TrimSpace(line)); { case strings.HasPrefix(cmd, "EHLO"), strings.HasPrefix(cmd, "HELO"): say("250 relay") case strings.HasPrefix(cmd, "DATA"): inData = true say("354 go on") case strings.HasPrefix(cmd, "QUIT"): say("221 bye") return default: say("250 ok") } } }() t.Cleanup(func() { _ = ln.Close() }) return ln.Addr().String(), got } func TestAMessageGoesThroughTheRelay(t *testing.T) { addr, got := relay(t) c := Config{SMTP: addr, From: "llmgw ", BaseURL: "https://llm.example.com"} if err := c.Validate(); err != nil { t.Fatal(err) } if err := c.Send(context.Background(), "ayse@example.com", "Set a new password", "Hello,\nthe link."); err != nil { t.Fatal(err) } msg := <-got for _, want := range []string{"Subject: Set a new password", "To: ayse@example.com", "Hello,\r\nthe link."} { if !strings.Contains(msg, want) { t.Errorf("the message lacks %q:\n%s", want, msg) } } } func TestHalfAMailConfigurationIsRefused(t *testing.T) { if err := (Config{}).Validate(); err != nil || (Config{}).Enabled() { t.Errorf("none: %v", err) } if err := (Config{SMTP: "smtp.example.com:587"}).Validate(); err == nil { t.Error("a relay without a sender was accepted") } if err := (Config{SMTP: "smtp.example.com:587", From: "a@b.c", BaseURL: "llm.example.com"}).Validate(); err == nil { t.Error("a base URL without a scheme was accepted") } if got := address("llmgw "); got != "llmgw@example.com" { t.Errorf("%q", got) } }