h
"). Build() data, err := json.Marshal(m) if err != nil { t.Fatal(err) } got, err := mailx.FromBytes(data) if err != nil { t.Fatal(err) } if got.From != "a@e.com" || got.Subject != "s" || got.Body != "h
" { t.Errorf("FromBytes mismatch: %+v", got) } } func TestFromBytesInvalid(t *testing.T) { if _, err := mailx.FromBytes([]byte("not json")); err == nil { t.Fatal("FromBytes(invalid) should error") } } func TestFromMap(t *testing.T) { m := map[string]any{ "from": "a@e.com", "to": "b@e.com, c@e.com", "cc": []string{"d@e.com"}, "subject": "hello", "text": "plain", "html": "hi", "replyto": "r@e.com", } msg, err := mailx.FromMap(m) if err != nil { t.Fatal(err) } if msg.From != "a@e.com" || msg.Subject != "hello" { t.Errorf("FromMap fields: %+v", msg) } if len(msg.To) != 2 || msg.To[0] != "b@e.com" || msg.To[1] != "c@e.com" { t.Errorf("FromMap To: %v", msg.To) } if len(msg.Cc) != 1 || msg.Cc[0] != "d@e.com" { t.Errorf("FromMap Cc: %v", msg.Cc) } if msg.TextBody != "plain" || msg.Body != "hi" { t.Errorf("FromMap bodies: text=%q html=%q", msg.TextBody, msg.Body) } if msg.ReplyTo != "r@e.com" { t.Errorf("FromMap ReplyTo: %q", msg.ReplyTo) } } func TestFromMapNil(t *testing.T) { if _, err := mailx.FromMap(nil); err == nil { t.Fatal("FromMap(nil) should error") } } func TestFromMapAttachments(t *testing.T) { m := map[string]any{ "to": "a@e.com", "attachments": []any{ map[string]any{"name": "x.txt", "path": "tmp/x.txt"}, }, } msg, err := mailx.FromMap(m) if err != nil { t.Fatal(err) } if len(msg.Attachments) != 1 || msg.Attachments[0].Name != "x.txt" { t.Errorf("FromMap attachments: %+v", msg.Attachments) } } // TestFromMapAttachmentNoName 验证附件 map 缺 name 键时不 panic,且 name 从 path 推导 func TestFromMapAttachmentNoName(t *testing.T) { m := map[string]any{ "to": "a@e.com", "attachments": []any{ map[string]any{"path": "tmp/report.pdf"}, // 无 name }, } msg, err := mailx.FromMap(m) if err != nil { t.Fatal(err) } if len(msg.Attachments) != 1 { t.Fatalf("attachments = %+v, want 1", msg.Attachments) } if msg.Attachments[0].Name != "report.pdf" { t.Errorf("Name = %q, want derived report.pdf", msg.Attachments[0].Name) } } // TestFromMapAttachmentTypeError 验证 attachments 类型非法时返回错误而非 panic func TestFromMapAttachmentTypeError(t *testing.T) { m := map[string]any{ "to": "a@e.com", "attachments": "not-a-list", // 非法类型 } if _, err := mailx.FromMap(m); err == nil { t.Fatal("FromMap with invalid attachments type should error") } } func TestIsHTML(t *testing.T) { cases := []struct { in string want bool }{ {"hi
", true}, {"h
", "replyto": "r@e.com", "attachments": [{"name": "a.txt", "data": "aGk="}], "inline": [{"cid": "cid1", "name": "i.png", "data": "aGk="}] }`) msg, err := mailx.FromBytes(data) if err != nil { t.Fatal(err) } if msg.From != "a@e.com" || len(msg.To) != 1 || msg.To[0] != "b@e.com" { t.Errorf("fields: %+v", msg) } if len(msg.Cc) != 1 || len(msg.Bcc) != 1 { t.Errorf("cc/bcc: %+v", msg) } if msg.TextBody != "t" || msg.Body != "h
" || msg.ReplyTo != "r@e.com" { t.Errorf("body fields: %+v", msg) } if len(msg.Attachments) != 1 || msg.Attachments[0].Name != "a.txt" { t.Errorf("attachments: %+v", msg.Attachments) } if len(msg.Inline) != 1 || msg.Inline[0].CID != "cid1" { t.Errorf("inline: %+v", msg.Inline) } }