mirror of
https://github.com/wneessen/go-mail.git
synced 2024-11-22 13:50:49 +01:00
feat: last tests
This commit is contained in:
parent
43ba8e3af2
commit
12076cf64a
2 changed files with 102 additions and 82 deletions
|
@ -16,9 +16,6 @@ var (
|
||||||
// ErrInvalidKeyPair should be used if key pair is invalid
|
// ErrInvalidKeyPair should be used if key pair is invalid
|
||||||
ErrInvalidKeyPair = errors.New("invalid key pair")
|
ErrInvalidKeyPair = errors.New("invalid key pair")
|
||||||
|
|
||||||
// ErrInvalidCertificate should be used if a certificate is invalid
|
|
||||||
ErrInvalidCertificate = errors.New("invalid certificate")
|
|
||||||
|
|
||||||
// ErrCouldNotInitialize should be used if the signed data could not initialize
|
// ErrCouldNotInitialize should be used if the signed data could not initialize
|
||||||
ErrCouldNotInitialize = errors.New("could not initialize signed data")
|
ErrCouldNotInitialize = errors.New("could not initialize signed data")
|
||||||
|
|
||||||
|
@ -36,7 +33,6 @@ var (
|
||||||
type SMime struct {
|
type SMime struct {
|
||||||
privateKey *rsa.PrivateKey
|
privateKey *rsa.PrivateKey
|
||||||
certificate *x509.Certificate
|
certificate *x509.Certificate
|
||||||
parentCertificates []*x509.Certificate
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewSMime construct a new instance of SMime with a provided *tls.Certificate
|
// NewSMime construct a new instance of SMime with a provided *tls.Certificate
|
||||||
|
@ -45,19 +41,9 @@ func newSMime(keyPair *tls.Certificate) (*SMime, error) {
|
||||||
return nil, ErrInvalidKeyPair
|
return nil, ErrInvalidKeyPair
|
||||||
}
|
}
|
||||||
|
|
||||||
parentCertificates := make([]*x509.Certificate, 0)
|
|
||||||
for _, cert := range keyPair.Certificate[1:] {
|
|
||||||
c, err := x509.ParseCertificate(cert)
|
|
||||||
if err != nil {
|
|
||||||
return nil, ErrInvalidCertificate
|
|
||||||
}
|
|
||||||
parentCertificates = append(parentCertificates, c)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &SMime{
|
return &SMime{
|
||||||
privateKey: keyPair.PrivateKey.(*rsa.PrivateKey),
|
privateKey: keyPair.PrivateKey.(*rsa.PrivateKey),
|
||||||
certificate: keyPair.Leaf,
|
certificate: keyPair.Leaf,
|
||||||
parentCertificates: parentCertificates,
|
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +58,7 @@ func (sm *SMime) signMessage(message string) (*string, error) {
|
||||||
return nil, ErrCouldNotInitialize
|
return nil, ErrCouldNotInitialize
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = signedData.AddSignerChain(sm.certificate, sm.privateKey, sm.parentCertificates, pkcs7.SignerInfoConfig{}); err != nil {
|
if err = signedData.AddSigner(sm.certificate, sm.privateKey, pkcs7.SignerInfoConfig{}); err != nil {
|
||||||
return nil, ErrCouldNotAddSigner
|
return nil, ErrCouldNotAddSigner
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,7 +78,7 @@ func (sm *SMime) signMessage(message string) (*string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// createMessage prepares the message that will be used for the sign method later
|
// createMessage prepares the message that will be used for the sign method later
|
||||||
func (sm *SMime) createMessage(encoding Encoding, contentType ContentType, charset Charset, body []byte) string {
|
func (sm *SMime) prepareMessage(encoding Encoding, contentType ContentType, charset Charset, body []byte) string {
|
||||||
return fmt.Sprintf("Content-Transfer-Encoding: %v\r\nContent-Type: %v; charset=%v\r\n\r\n%v", encoding, contentType, charset, string(body))
|
return fmt.Sprintf("Content-Transfer-Encoding: %v\r\nContent-Type: %v; charset=%v\r\n\r\n%v", encoding, contentType, charset, string(body))
|
||||||
}
|
}
|
||||||
|
|
150
smime_test.go
150
smime_test.go
|
@ -1,7 +1,8 @@
|
||||||
package mail
|
package mail
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"bytes"
|
||||||
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -25,9 +26,6 @@ func TestNewSMime(t *testing.T) {
|
||||||
if sMime.certificate != keyPair.Leaf {
|
if sMime.certificate != keyPair.Leaf {
|
||||||
t.Errorf("NewSMime() did not return the same leaf certificate")
|
t.Errorf("NewSMime() did not return the same leaf certificate")
|
||||||
}
|
}
|
||||||
if len(sMime.parentCertificates) != len(keyPair.Certificate)-1 {
|
|
||||||
t.Errorf("NewSMime() did not return the same number of parentCertificates")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestSign tests the sign method
|
// TestSign tests the sign method
|
||||||
|
@ -41,11 +39,20 @@ func TestSign(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Error creating new SMime from keyPair: %s", err)
|
t.Errorf("Error creating new SMime from keyPair: %s", err)
|
||||||
}
|
}
|
||||||
fmt.Println(sMime)
|
|
||||||
|
message := "This is a test message"
|
||||||
|
singedMessage, err := sMime.signMessage(message)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Error creating singed message: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestCreateMessage tests the createMessage method
|
if *singedMessage == message {
|
||||||
func TestCreateMessage(t *testing.T) {
|
t.Errorf("Sign() did not work")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestPrepareMessage tests the createMessage method
|
||||||
|
func TestPrepareMessage(t *testing.T) {
|
||||||
keyPair, err := getDummyCertificate()
|
keyPair, err := getDummyCertificate()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Error getting dummy certificate: %s", err)
|
t.Errorf("Error getting dummy certificate: %s", err)
|
||||||
|
@ -60,7 +67,7 @@ func TestCreateMessage(t *testing.T) {
|
||||||
contentType := TypeTextPlain
|
contentType := TypeTextPlain
|
||||||
charset := CharsetUTF8
|
charset := CharsetUTF8
|
||||||
body := []byte("This is the body!")
|
body := []byte("This is the body!")
|
||||||
result := sMime.createMessage(encoding, contentType, body)
|
result := sMime.prepareMessage(encoding, contentType, charset, body)
|
||||||
|
|
||||||
if !strings.Contains(result, encoding.String()) {
|
if !strings.Contains(result, encoding.String()) {
|
||||||
t.Errorf("createMessage() did not return the correct encoding")
|
t.Errorf("createMessage() did not return the correct encoding")
|
||||||
|
@ -71,86 +78,113 @@ func TestCreateMessage(t *testing.T) {
|
||||||
if !strings.Contains(result, string(body)) {
|
if !strings.Contains(result, string(body)) {
|
||||||
t.Errorf("createMessage() did not return the correct body")
|
t.Errorf("createMessage() did not return the correct body")
|
||||||
}
|
}
|
||||||
if result != fmt.Sprintf("Content-Transfer-Encoding: %v\r\nContent-Type: %v; charset=%v\r\n\r\n%v", encoding, contentType, charset, string(body)) {
|
if result != fmt.Sprintf("Content-Transfer-Encoding: %s\r\nContent-Type: %s; charset=%s\r\n\r\n%s", encoding, contentType, charset, string(body)) {
|
||||||
t.Errorf("createMessage() did not sucessfully create the message")
|
t.Errorf("createMessage() did not sucessfully create the message")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestEncodeToPEM tests the encodeToPEM method
|
// TestEncodeToPEM tests the encodeToPEM method
|
||||||
func TestEncodeToPEM(t *testing.T) {
|
func TestEncodeToPEM(t *testing.T) {
|
||||||
|
message := []byte("This is a test message")
|
||||||
|
|
||||||
keyPair, err := getDummyCertificate()
|
pemMessage, err := encodeToPEM(message)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Error getting dummy certificate: %s", err)
|
t.Errorf("Error encoding message: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
sMime, err := newSMime(keyPair)
|
base64Encoded := base64.StdEncoding.EncodeToString(message)
|
||||||
if err != nil {
|
if *pemMessage != base64Encoded {
|
||||||
t.Errorf("Error creating new SMime from keyPair: %s", err)
|
t.Errorf("encodeToPEM() did not work")
|
||||||
}
|
}
|
||||||
fmt.Println(sMime)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestBytesFromLines tests the bytesFromLines method
|
// TestBytesFromLines tests the bytesFromLines method
|
||||||
func TestBytesFromLines(t *testing.T) {
|
func TestBytesFromLines(t *testing.T) {
|
||||||
|
ls := lines{
|
||||||
|
{line: []byte("Hello"), endOfLine: []byte("\n")},
|
||||||
|
{line: []byte("World"), endOfLine: []byte("\n")},
|
||||||
|
}
|
||||||
|
expected := []byte("Hello\nWorld\n")
|
||||||
|
|
||||||
|
result := ls.bytesFromLines([]byte("\n"))
|
||||||
|
if !bytes.Equal(result, expected) {
|
||||||
|
t.Errorf("Expected %s, but got %s", expected, result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FuzzBytesFromLines tests the bytesFromLines method with fuzzing
|
||||||
|
func FuzzBytesFromLines(f *testing.F) {
|
||||||
|
f.Add([]byte("Hello"), []byte("\n"))
|
||||||
|
f.Fuzz(func(t *testing.T, lineData, sep []byte) {
|
||||||
|
ls := lines{
|
||||||
|
{line: lineData, endOfLine: sep},
|
||||||
|
}
|
||||||
|
_ = ls.bytesFromLines(sep)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestParseLines tests the parseLines method
|
// TestParseLines tests the parseLines method
|
||||||
func TestParseLines(t *testing.T) {
|
func TestParseLines(t *testing.T) {
|
||||||
|
input := []byte("Hello\r\nWorld\nHello\rWorld")
|
||||||
|
expected := lines{
|
||||||
|
{line: []byte("Hello"), endOfLine: []byte("\r\n")},
|
||||||
|
{line: []byte("World"), endOfLine: []byte("\n")},
|
||||||
|
{line: []byte("Hello"), endOfLine: []byte("\r")},
|
||||||
|
{line: []byte("World"), endOfLine: []byte("")},
|
||||||
|
}
|
||||||
|
|
||||||
|
result := parseLines(input)
|
||||||
|
if len(result) != len(expected) {
|
||||||
|
t.Errorf("Expected %d lines, but got %d", len(expected), len(result))
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range result {
|
||||||
|
if !bytes.Equal(result[i].line, expected[i].line) || !bytes.Equal(result[i].endOfLine, expected[i].endOfLine) {
|
||||||
|
t.Errorf("Line %d mismatch. Expected line: %s, endOfLine: %s, got line: %s, endOfLine: %s",
|
||||||
|
i, expected[i].line, expected[i].endOfLine, result[i].line, result[i].endOfLine)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FuzzParseLines tests the parseLines method with fuzzing
|
||||||
|
func FuzzParseLines(f *testing.F) {
|
||||||
|
f.Add([]byte("Hello\nWorld\r\nAnother\rLine"))
|
||||||
|
f.Fuzz(func(t *testing.T, input []byte) {
|
||||||
|
_ = parseLines(input)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestSplitLine tests the splitLine method
|
// TestSplitLine tests the splitLine method
|
||||||
func TestSplitLine(t *testing.T) {
|
func TestSplitLine(t *testing.T) {
|
||||||
|
ls := lines{
|
||||||
|
{line: []byte("Hello\r\nWorld\r\nAnotherLine"), endOfLine: []byte("")},
|
||||||
|
}
|
||||||
|
expected := lines{
|
||||||
|
{line: []byte("Hello"), endOfLine: []byte("\r\n")},
|
||||||
|
{line: []byte("World"), endOfLine: []byte("\r\n")},
|
||||||
|
{line: []byte("AnotherLine"), endOfLine: []byte("")},
|
||||||
}
|
}
|
||||||
|
|
||||||
func foo(t *testing.T) {
|
result := ls.splitLine([]byte("\r\n"))
|
||||||
tl := []struct {
|
if len(result) != len(expected) {
|
||||||
n string
|
t.Errorf("Expected %d lines, but got %d", len(expected), len(result))
|
||||||
r SendErrReason
|
|
||||||
te bool
|
|
||||||
}{
|
|
||||||
{"ErrGetSender/temp", ErrGetSender, true},
|
|
||||||
{"ErrGetSender/perm", ErrGetSender, false},
|
|
||||||
{"ErrGetRcpts/temp", ErrGetRcpts, true},
|
|
||||||
{"ErrGetRcpts/perm", ErrGetRcpts, false},
|
|
||||||
{"ErrSMTPMailFrom/temp", ErrSMTPMailFrom, true},
|
|
||||||
{"ErrSMTPMailFrom/perm", ErrSMTPMailFrom, false},
|
|
||||||
{"ErrSMTPRcptTo/temp", ErrSMTPRcptTo, true},
|
|
||||||
{"ErrSMTPRcptTo/perm", ErrSMTPRcptTo, false},
|
|
||||||
{"ErrSMTPData/temp", ErrSMTPData, true},
|
|
||||||
{"ErrSMTPData/perm", ErrSMTPData, false},
|
|
||||||
{"ErrSMTPDataClose/temp", ErrSMTPDataClose, true},
|
|
||||||
{"ErrSMTPDataClose/perm", ErrSMTPDataClose, false},
|
|
||||||
{"ErrSMTPReset/temp", ErrSMTPReset, true},
|
|
||||||
{"ErrSMTPReset/perm", ErrSMTPReset, false},
|
|
||||||
{"ErrWriteContent/temp", ErrWriteContent, true},
|
|
||||||
{"ErrWriteContent/perm", ErrWriteContent, false},
|
|
||||||
{"ErrConnCheck/temp", ErrConnCheck, true},
|
|
||||||
{"ErrConnCheck/perm", ErrConnCheck, false},
|
|
||||||
{"ErrNoUnencoded/temp", ErrNoUnencoded, true},
|
|
||||||
{"ErrNoUnencoded/perm", ErrNoUnencoded, false},
|
|
||||||
{"ErrAmbiguous/temp", ErrAmbiguous, true},
|
|
||||||
{"ErrAmbiguous/perm", ErrAmbiguous, false},
|
|
||||||
{"Unknown/temp", 9999, true},
|
|
||||||
{"Unknown/perm", 9999, false},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tt := range tl {
|
for i := range result {
|
||||||
t.Run(tt.n, func(t *testing.T) {
|
if !bytes.Equal(result[i].line, expected[i].line) || !bytes.Equal(result[i].endOfLine, expected[i].endOfLine) {
|
||||||
if err := returnSendError(tt.r, tt.te); err != nil {
|
t.Errorf("Line %d mismatch. Expected line: %s, endOfLine: %s, got line: %s, endOfLine: %s",
|
||||||
exp := &SendError{Reason: tt.r, isTemp: tt.te}
|
i, expected[i].line, expected[i].endOfLine, result[i].line, result[i].endOfLine)
|
||||||
if !errors.Is(err, exp) {
|
|
||||||
t.Errorf("error mismatch, expected: %s (temp: %t), got: %s (temp: %t)", tt.r, tt.te,
|
|
||||||
exp.Error(), exp.isTemp)
|
|
||||||
}
|
|
||||||
if !strings.Contains(fmt.Sprintf("%s", err), tt.r.String()) {
|
|
||||||
t.Errorf("error string mismatch, expected: %s, got: %s",
|
|
||||||
tt.r.String(), fmt.Sprintf("%s", err))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FuzzSplitLine tests the parseLsplitLineines method with fuzzing
|
||||||
|
func FuzzSplitLine(f *testing.F) {
|
||||||
|
f.Add([]byte("Hello\r\nWorld"), []byte("\r\n"))
|
||||||
|
f.Fuzz(func(t *testing.T, input, sep []byte) {
|
||||||
|
ls := lines{
|
||||||
|
{line: input, endOfLine: []byte("")},
|
||||||
|
}
|
||||||
|
_ = ls.splitLine(sep)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue