diff --git a/msg.go b/msg.go index 029ae65..db019e6 100644 --- a/msg.go +++ b/msg.go @@ -483,6 +483,11 @@ func (m *Msg) GetGenHeader(h Header) []string { 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. func (m *Msg) SetBodyString(ct ContentType, b string, o ...PartOption) { buf := bytes.NewBufferString(b) diff --git a/part.go b/part.go index d1996d6..0bd0136 100644 --- a/part.go +++ b/part.go @@ -4,7 +4,10 @@ package mail -import "io" +import ( + "bytes" + "io" +) // PartOption returns a function that can be used for grouping Part options type PartOption func(*Part) @@ -16,11 +19,45 @@ type Part struct { 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 +} + +// 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 func (p *Part) SetEncoding(e Encoding) { 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 func WithPartEncoding(e Encoding) PartOption { return func(p *Part) { diff --git a/part_test.go b/part_test.go index 3a567b8..09f01bf 100644 --- a/part_test.go +++ b/part_test.go @@ -4,7 +4,11 @@ package mail -import "testing" +import ( + "bytes" + "fmt" + "testing" +) // TestPartEncoding tests the WithPartEncoding and Part.SetEncoding methods func TestPartEncoding(t *testing.T) { @@ -38,3 +42,88 @@ func TestPartEncoding(t *testing.T) { }) } } + +// 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()) + } +} + +// 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 +}