package googleapi import ( "git.blackforestbytes.com/BlackForestBytes/goext/tst" "strings" "testing" ) func TestMimeMailPlainOnly(t *testing.T) { mail := encodeMimeMail( "from@example.com", []string{"to@example.com"}, nil, nil, nil, "Test Subject", MailBody{Plain: "Hello plain body"}, nil) tst.AssertTrue(t, strings.Contains(mail, "From: from@example.com")) tst.AssertTrue(t, strings.Contains(mail, "To: to@example.com")) tst.AssertTrue(t, strings.Contains(mail, "Subject: Test Subject")) tst.AssertTrue(t, strings.Contains(mail, "Content-Type: text/plain; charset=UTF-8")) tst.AssertTrue(t, strings.Contains(mail, "Content-Transfer-Encoding: 7bit")) tst.AssertTrue(t, strings.Contains(mail, "Hello plain body")) tst.AssertTrue(t, strings.Contains(mail, "MIME-Version: 1.0")) // Each line must be terminated by CRLF. tst.AssertTrue(t, strings.Contains(mail, "\r\n")) } func TestMimeMailHTMLOnly(t *testing.T) { mail := encodeMimeMail( "from@example.com", []string{"to@example.com"}, nil, nil, nil, "S", MailBody{HTML: "

Hi

"}, nil) tst.AssertTrue(t, strings.Contains(mail, "Content-Type: text/html; charset=UTF-8")) tst.AssertTrue(t, strings.Contains(mail, "

Hi

")) tst.AssertFalse(t, strings.Contains(mail, "multipart/")) } func TestMimeMailAlternative(t *testing.T) { mail := encodeMimeMail( "from@example.com", []string{"to@example.com"}, nil, nil, nil, "S", MailBody{ Plain: "Plain Body", HTML: "

HTML Body

", }, nil) tst.AssertTrue(t, strings.Contains(mail, "Content-Type: multipart/alternative;")) tst.AssertTrue(t, strings.Contains(mail, "Plain Body")) tst.AssertTrue(t, strings.Contains(mail, "

HTML Body

")) tst.AssertTrue(t, strings.Contains(mail, "Content-Type: text/plain; charset=UTF-8")) tst.AssertTrue(t, strings.Contains(mail, "Content-Type: text/html; charset=UTF-8")) } func TestMimeMailWithCC(t *testing.T) { mail := encodeMimeMail( "from@example.com", []string{"to@example.com"}, []string{"cc@example.com"}, nil, nil, "S", MailBody{Plain: "x"}, nil) tst.AssertTrue(t, strings.Contains(mail, "cc@example.com")) } func TestMimeMailWithBCC(t *testing.T) { mail := encodeMimeMail( "from@example.com", []string{"to@example.com"}, nil, []string{"bcc@example.com"}, nil, "S", MailBody{Plain: "x"}, nil) tst.AssertTrue(t, strings.Contains(mail, "Bcc: bcc@example.com")) } func TestMimeMailWithReplyTo(t *testing.T) { mail := encodeMimeMail( "from@example.com", []string{"to@example.com"}, nil, nil, []string{"reply@example.com"}, "S", MailBody{Plain: "x"}, nil) tst.AssertTrue(t, strings.Contains(mail, "Reply-To: reply@example.com")) } func TestMimeMailMultipleRecipients(t *testing.T) { mail := encodeMimeMail( "from@example.com", []string{"a@example.com", "b@example.com", "c@example.com"}, nil, nil, nil, "S", MailBody{Plain: "x"}, nil) tst.AssertTrue(t, strings.Contains(mail, "a@example.com")) tst.AssertTrue(t, strings.Contains(mail, "b@example.com")) tst.AssertTrue(t, strings.Contains(mail, "c@example.com")) tst.AssertTrue(t, strings.Contains(mail, "a@example.com, b@example.com, c@example.com")) } func TestMimeMailSubjectEncoding(t *testing.T) { mail := encodeMimeMail( "from@example.com", []string{"to@example.com"}, nil, nil, nil, "Hällö Wörld", MailBody{Plain: "x"}, nil) // Non-ASCII subject must be quoted-printable encoded. tst.AssertTrue(t, strings.Contains(mail, "Subject: =?UTF-8?q?")) } func TestMimeMailWithNormalAttachment(t *testing.T) { mail := encodeMimeMail( "from@example.com", []string{"to@example.com"}, nil, nil, nil, "S", MailBody{Plain: "Body"}, []MailAttachment{ {Data: []byte("attached"), Filename: "f.txt", IsInline: false, ContentType: "text/plain"}, }) tst.AssertTrue(t, strings.Contains(mail, "Content-Type: multipart/mixed;")) tst.AssertTrue(t, strings.Contains(mail, `Content-Disposition: attachment;filename="f.txt"`)) } func TestMimeMailWithInlineAttachment(t *testing.T) { mail := encodeMimeMail( "from@example.com", []string{"to@example.com"}, nil, nil, nil, "S", MailBody{HTML: "

x

"}, []MailAttachment{ {Data: []byte{1, 2, 3}, Filename: "img.png", IsInline: true, ContentType: "image/png"}, }) tst.AssertTrue(t, strings.Contains(mail, "Content-Type: multipart/related;")) tst.AssertTrue(t, strings.Contains(mail, `Content-Disposition: inline;filename="img.png"`)) } func TestMimeMailWithBothAttachmentTypes(t *testing.T) { mail := encodeMimeMail( "from@example.com", []string{"to@example.com"}, nil, nil, nil, "S", MailBody{HTML: "

x

"}, []MailAttachment{ {Data: []byte{1}, Filename: "img.png", IsInline: true, ContentType: "image/png"}, {Data: []byte{2}, Filename: "f.txt", IsInline: false, ContentType: "text/plain"}, }) tst.AssertTrue(t, strings.Contains(mail, "Content-Type: multipart/mixed;")) tst.AssertTrue(t, strings.Contains(mail, "Content-Type: multipart/related;")) tst.AssertTrue(t, strings.Contains(mail, `Content-Disposition: inline;filename="img.png"`)) tst.AssertTrue(t, strings.Contains(mail, `Content-Disposition: attachment;filename="f.txt"`)) } func TestMimeMailEmptyBody(t *testing.T) { mail := encodeMimeMail( "from@example.com", []string{"to@example.com"}, nil, nil, nil, "S", MailBody{}, nil) tst.AssertTrue(t, strings.Contains(mail, "From: from@example.com")) tst.AssertTrue(t, strings.Contains(mail, "To: to@example.com")) tst.AssertTrue(t, strings.Contains(mail, "Subject: S")) // No body type was set, so no Content-Type for body should be present. tst.AssertFalse(t, strings.Contains(mail, "Content-Type: text/")) tst.AssertFalse(t, strings.Contains(mail, "Content-Type: multipart/")) } func TestMimeMailHasDateHeader(t *testing.T) { mail := encodeMimeMail( "from@example.com", []string{"to@example.com"}, nil, nil, nil, "S", MailBody{Plain: "x"}, nil) tst.AssertTrue(t, strings.HasPrefix(mail, "Date: ")) } func TestDumpMailBodyPlainOnly(t *testing.T) { lines := dumpMailBody(MailBody{Plain: "Plain"}, false, false, "BOUND", "BOUNDALT") joined := strings.Join(lines, "\n") tst.AssertTrue(t, strings.Contains(joined, "--BOUND")) tst.AssertTrue(t, strings.Contains(joined, "Content-Type: text/plain; charset=UTF-8")) tst.AssertTrue(t, strings.Contains(joined, "Plain")) } func TestDumpMailBodyHTMLOnly(t *testing.T) { lines := dumpMailBody(MailBody{HTML: "

x

"}, false, false, "BOUND", "BOUNDALT") joined := strings.Join(lines, "\n") tst.AssertTrue(t, strings.Contains(joined, "--BOUND")) tst.AssertTrue(t, strings.Contains(joined, "Content-Type: text/html; charset=UTF-8")) tst.AssertTrue(t, strings.Contains(joined, "

x

")) } func TestDumpMailBodyEmpty(t *testing.T) { lines := dumpMailBody(MailBody{}, false, false, "BOUND", "BOUNDALT") joined := strings.Join(lines, "\n") // Default empty case still emits the boundary and a default Content-Type header. tst.AssertTrue(t, strings.Contains(joined, "--BOUND")) tst.AssertTrue(t, strings.Contains(joined, "Content-Type: text/plain; charset=UTF-8")) } func TestDumpMailBodyMixedAlternative(t *testing.T) { // HTML+Plain with normal attachments and no inline → uses alternative sub-block. lines := dumpMailBody(MailBody{Plain: "P", HTML: "

H

"}, false, true, "BOUND", "BOUNDALT") joined := strings.Join(lines, "\n") tst.AssertTrue(t, strings.Contains(joined, "--BOUND")) tst.AssertTrue(t, strings.Contains(joined, "Content-Type: multipart/alternative; boundary=BOUNDALT")) tst.AssertTrue(t, strings.Contains(joined, "--BOUNDALT")) tst.AssertTrue(t, strings.Contains(joined, "P")) tst.AssertTrue(t, strings.Contains(joined, "

H

")) } func TestDumpMailBodyMixedInline(t *testing.T) { // HTML+Plain with inline attachments → simplified to single HTML block. lines := dumpMailBody(MailBody{Plain: "P", HTML: "

H

"}, true, false, "BOUND", "BOUNDALT") tst.AssertEqual(t, len(lines), 2) tst.AssertEqual(t, lines[0], "--BOUND") tst.AssertEqual(t, lines[1], "

H

") } func TestDumpMailBodyBothNoAttachments(t *testing.T) { lines := dumpMailBody(MailBody{Plain: "P", HTML: "

H

"}, false, false, "BOUND", "BOUNDALT") joined := strings.Join(lines, "\n") tst.AssertTrue(t, strings.Contains(joined, "--BOUND")) tst.AssertTrue(t, strings.Contains(joined, "Content-Type: text/plain; charset=UTF-8")) tst.AssertTrue(t, strings.Contains(joined, "Content-Type: text/html; charset=UTF-8")) tst.AssertTrue(t, strings.Contains(joined, "P")) tst.AssertTrue(t, strings.Contains(joined, "

H

")) }