mirror of
https://github.com/wneessen/go-mail.git
synced 2024-11-22 13:50:49 +01:00
Merge pull request #61 from wneessen/60-expose-msg-fields
Expose Msg bodypart fields
This commit is contained in:
commit
a3a2b0e4b4
3 changed files with 261 additions and 2 deletions
5
msg.go
5
msg.go
|
@ -483,6 +483,11 @@ func (m *Msg) GetGenHeader(h Header) []string {
|
||||||
return m.genHeader[h]
|
return m.genHeader[h]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetParts returns the message parts of the Msg
|
||||||
|
func (m *Msg) GetParts() []*Part {
|
||||||
|
return m.parts
|
||||||
|
}
|
||||||
|
|
||||||
// SetBodyString sets the body of the message.
|
// SetBodyString sets the body of the message.
|
||||||
func (m *Msg) SetBodyString(ct ContentType, b string, o ...PartOption) {
|
func (m *Msg) SetBodyString(ct ContentType, b string, o ...PartOption) {
|
||||||
buf := bytes.NewBufferString(b)
|
buf := bytes.NewBufferString(b)
|
||||||
|
|
45
part.go
45
part.go
|
@ -4,7 +4,10 @@
|
||||||
|
|
||||||
package mail
|
package mail
|
||||||
|
|
||||||
import "io"
|
import (
|
||||||
|
"bytes"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
// PartOption returns a function that can be used for grouping Part options
|
// PartOption returns a function that can be used for grouping Part options
|
||||||
type PartOption func(*Part)
|
type PartOption func(*Part)
|
||||||
|
@ -16,11 +19,51 @@ type Part struct {
|
||||||
w func(io.Writer) (int64, error)
|
w func(io.Writer) (int64, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetContent executes the WriteFunc of the Part and returns the content as byte slice
|
||||||
|
func (p *Part) GetContent() ([]byte, error) {
|
||||||
|
var b bytes.Buffer
|
||||||
|
if _, err := p.w(&b); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return b.Bytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetContentType returns the currently set ContentType of the Part
|
||||||
|
func (p *Part) GetContentType() ContentType {
|
||||||
|
return p.ctype
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetEncoding returns the currently set Encoding of the Part
|
||||||
|
func (p *Part) GetEncoding() Encoding {
|
||||||
|
return p.enc
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetWriteFunc returns the currently set WriterFunc of the Part
|
||||||
|
func (p *Part) GetWriteFunc() func(io.Writer) (int64, error) {
|
||||||
|
return p.w
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetContent overrides the content of the Part with the given string
|
||||||
|
func (p *Part) SetContent(c string) {
|
||||||
|
buf := bytes.NewBufferString(c)
|
||||||
|
p.w = writeFuncFromBuffer(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetContentType overrides the ContentType of the Part
|
||||||
|
func (p *Part) SetContentType(c ContentType) {
|
||||||
|
p.ctype = c
|
||||||
|
}
|
||||||
|
|
||||||
// SetEncoding creates a new mime.WordEncoder based on the encoding setting of the message
|
// SetEncoding creates a new mime.WordEncoder based on the encoding setting of the message
|
||||||
func (p *Part) SetEncoding(e Encoding) {
|
func (p *Part) SetEncoding(e Encoding) {
|
||||||
p.enc = e
|
p.enc = e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetWriteFunc overrides the WriteFunc of the Part
|
||||||
|
func (p *Part) SetWriteFunc(w func(io.Writer) (int64, error)) {
|
||||||
|
p.w = w
|
||||||
|
}
|
||||||
|
|
||||||
// WithPartEncoding overrides the default Part encoding
|
// WithPartEncoding overrides the default Part encoding
|
||||||
func WithPartEncoding(e Encoding) PartOption {
|
func WithPartEncoding(e Encoding) PartOption {
|
||||||
return func(p *Part) {
|
return func(p *Part) {
|
||||||
|
|
213
part_test.go
213
part_test.go
|
@ -4,7 +4,13 @@
|
||||||
|
|
||||||
package mail
|
package mail
|
||||||
|
|
||||||
import "testing"
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
// TestPartEncoding tests the WithPartEncoding and Part.SetEncoding methods
|
// TestPartEncoding tests the WithPartEncoding and Part.SetEncoding methods
|
||||||
func TestPartEncoding(t *testing.T) {
|
func TestPartEncoding(t *testing.T) {
|
||||||
|
@ -38,3 +44,208 @@ func TestPartEncoding(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestPartContentType tests Part.SetContentType
|
||||||
|
func TestPart_SetContentType(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
ct ContentType
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
{"ContentType: text/plain", TypeTextPlain, "text/plain"},
|
||||||
|
{"ContentType: text/html", TypeTextHTML, "text/html"},
|
||||||
|
{"ContentType: application/json", "application/json", "application/json"},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
m := NewMsg()
|
||||||
|
m.SetBodyString(TypeTextPlain, "This is a test with ümläutß")
|
||||||
|
pl, err := getPartList(m)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
pl[0].SetContentType(tt.ct)
|
||||||
|
ct := pl[0].GetContentType()
|
||||||
|
if string(ct) != tt.want {
|
||||||
|
t.Errorf("SetContentType failed. Got: %s, expected: %s", string(ct), tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestPartEncoding tests Part.GetEncoding
|
||||||
|
func TestPart_GetEncoding(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
enc Encoding
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
{"Part encoding: Base64", EncodingB64, "base64"},
|
||||||
|
{"Part encoding: Quoted-Printable", EncodingQP, "quoted-printable"},
|
||||||
|
{"Part encoding: 8bit", NoEncoding, "8bit"},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
m := NewMsg()
|
||||||
|
m.SetBodyString(TypeTextPlain, "This is a test with ümläutß", WithPartEncoding(tt.enc))
|
||||||
|
pl, err := getPartList(m)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
e := pl[0].GetEncoding()
|
||||||
|
if e.String() != tt.want {
|
||||||
|
t.Errorf("Part.GetEncoding failed. Expected: %s, got: %s", tt.want, e.String())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestPart_GetContentType tests Part.GetContentType
|
||||||
|
func TestPart_GetContentType(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
ct ContentType
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
{"ContentType: text/plain", TypeTextPlain, "text/plain"},
|
||||||
|
{"ContentType: text/html", TypeTextHTML, "text/html"},
|
||||||
|
{"ContentType: application/json", "application/json", "application/json"},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
m := NewMsg()
|
||||||
|
m.SetBodyString(tt.ct, "This is a test with ümläutß")
|
||||||
|
pl, err := getPartList(m)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c := pl[0].GetContentType()
|
||||||
|
if string(c) != tt.want {
|
||||||
|
t.Errorf("Part.GetContentType failed. Expected: %s, got: %s", tt.want, string(c))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestPart_GetWriteFunc tests Part.GetWriteFunc
|
||||||
|
func TestPart_GetWriteFunc(t *testing.T) {
|
||||||
|
c := "This is a test with ümläutß"
|
||||||
|
m := NewMsg()
|
||||||
|
m.SetBodyString(TypeTextPlain, c)
|
||||||
|
pl, err := getPartList(m)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
wf := pl[0].GetWriteFunc()
|
||||||
|
var b bytes.Buffer
|
||||||
|
if _, err := wf(&b); err != nil {
|
||||||
|
t.Errorf("failed to execute writefunc: %s", err)
|
||||||
|
}
|
||||||
|
if b.String() != c {
|
||||||
|
t.Errorf("GetWriteFunc failed. Expected: %s, got: %s", c, b.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestPart_GetContent tests Part.GetContent
|
||||||
|
func TestPart_GetContent(t *testing.T) {
|
||||||
|
c := "This is a test with ümläutß"
|
||||||
|
m := NewMsg()
|
||||||
|
m.SetBodyString(TypeTextPlain, c)
|
||||||
|
pl, err := getPartList(m)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
cb, err := pl[0].GetContent()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Part.GetContent failed: %s", err)
|
||||||
|
}
|
||||||
|
if string(cb) != c {
|
||||||
|
t.Errorf("Part.GetContent failed. Expected: %s, got: %s", c, string(cb))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestPart_GetContentBroken tests Part.GetContent
|
||||||
|
func TestPart_GetContentBroken(t *testing.T) {
|
||||||
|
c := "This is a test with ümläutß"
|
||||||
|
m := NewMsg()
|
||||||
|
m.SetBodyString(TypeTextPlain, c)
|
||||||
|
pl, err := getPartList(m)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
pl[0].w = func(io.Writer) (int64, error) {
|
||||||
|
return 0, fmt.Errorf("broken")
|
||||||
|
}
|
||||||
|
_, err = pl[0].GetContent()
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("Part.GetContent was supposed to failed, but didn't")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestPart_SetWriteFunc tests Part.SetWriteFunc
|
||||||
|
func TestPart_SetWriteFunc(t *testing.T) {
|
||||||
|
c := "This is a test with ümläutß"
|
||||||
|
m := NewMsg()
|
||||||
|
m.SetBodyString(TypeTextPlain, c)
|
||||||
|
pl, err := getPartList(m)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
cb, err := pl[0].GetContent()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Part.GetContent failed: %s", err)
|
||||||
|
}
|
||||||
|
pl[0].SetWriteFunc(func(w io.Writer) (int64, error) {
|
||||||
|
ns := strings.ToUpper(string(cb))
|
||||||
|
buf := bytes.NewBufferString(ns)
|
||||||
|
nb, err := w.Write(buf.Bytes())
|
||||||
|
return int64(nb), err
|
||||||
|
})
|
||||||
|
nc, err := pl[0].GetContent()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Part.GetContent failed: %s", err)
|
||||||
|
}
|
||||||
|
if string(nc) != strings.ToUpper(c) {
|
||||||
|
t.Errorf("SetWriteFunc failed. Expected: %s, got: %s", strings.ToUpper(c), string(nc))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestPart_SetContent tests Part.SetContent
|
||||||
|
func TestPart_SetContent(t *testing.T) {
|
||||||
|
c := "This is a test with ümläutß"
|
||||||
|
m := NewMsg()
|
||||||
|
m.SetBodyString(TypeTextPlain, c)
|
||||||
|
pl, err := getPartList(m)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
cb, err := pl[0].GetContent()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Part.GetContent failed: %s", err)
|
||||||
|
}
|
||||||
|
pl[0].SetContent(strings.ToUpper(string(cb)))
|
||||||
|
nc, err := pl[0].GetContent()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Part.GetContent failed: %s", err)
|
||||||
|
}
|
||||||
|
if string(nc) != strings.ToUpper(c) {
|
||||||
|
t.Errorf("SetContent failed. Expected: %s, got: %s", strings.ToUpper(c), string(nc))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// getPartList is a helper function
|
||||||
|
func getPartList(m *Msg) ([]*Part, error) {
|
||||||
|
pl := m.GetParts()
|
||||||
|
if len(pl) <= 0 {
|
||||||
|
return nil, fmt.Errorf("Msg.GetParts failed. Part list is empty")
|
||||||
|
}
|
||||||
|
return pl, nil
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue