Abin Simon b896405e92
Add tests to check for invalid email addresses in eml export (#4881)
<!-- PR description-->

---

#### Does this PR need a docs update or release note?

- [ ]  Yes, it's included
- [ ] 🕐 Yes, but in a later PR
- [x]  No

#### Type of change

<!--- Please check the type of change your PR introduces: --->
- [ ] 🌻 Feature
- [ ] 🐛 Bugfix
- [ ] 🗺️ Documentation
- [x] 🤖 Supportability/Tests
- [ ] 💻 CI/Deployment
- [ ] 🧹 Tech Debt/Cleanup

#### Issue(s)

<!-- Can reference multiple issues. Use one of the following "magic words" - "closes, fixes" to auto-close the Github issue. -->
* #<issue>

#### Test Plan

<!-- How will this be tested prior to merging.-->
- [ ] 💪 Manual
- [x]  Unit test
- [ ] 💚 E2E
2023-12-19 19:41:42 +00:00

191 lines
4.7 KiB
Go

package eml
import (
"regexp"
"strings"
"testing"
"time"
"github.com/jhillyerd/enmime"
kjson "github.com/microsoft/kiota-serialization-json-go"
"github.com/microsoftgraph/msgraph-sdk-go/models"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
"github.com/alcionai/corso/src/internal/common/ptr"
"github.com/alcionai/corso/src/internal/converters/eml/testdata"
"github.com/alcionai/corso/src/internal/tester"
"github.com/alcionai/corso/src/pkg/services/m365/api"
)
type EMLUnitSuite struct {
tester.Suite
}
func TestEMLUnitSuite(t *testing.T) {
suite.Run(t, &EMLUnitSuite{Suite: tester.NewUnitSuite(t)})
}
func (suite *EMLUnitSuite) TestFormatAddress() {
t := suite.T()
tests := []struct {
tname string
name string
email string
expected string
}{
{
tname: "different name and email",
name: "John Doe",
email: "johndoe@provider.com",
expected: `"John Doe" <johndoe@provider.com>`,
},
{
tname: "same name and email",
name: "johndoe@provider.com",
email: "johndoe@provider.com",
expected: "johndoe@provider.com",
},
{
tname: "only email",
name: "",
email: "johndoe@provider.com",
expected: "johndoe@provider.com",
},
{
tname: "only name",
name: "john doe",
email: "",
expected: `"john doe"`,
},
{
tname: "neither mail or name",
name: "",
email: "",
expected: "",
},
}
for _, tt := range tests {
t.Run(tt.tname, func(t *testing.T) {
entity := models.NewEmailAddress()
if len(tt.name) != 0 {
entity.SetName(ptr.To(tt.name))
}
if len(tt.email) != 0 {
entity.SetAddress(ptr.To(tt.email))
}
assert.Equal(t, tt.expected, formatAddress(entity))
})
}
}
func (suite *EMLUnitSuite) TestConvert_messageble_to_eml() {
t := suite.T()
ctx, flush := tester.NewContext(t)
defer flush()
body := []byte(testdata.EmailWithAttachments)
out, err := FromJSON(ctx, body)
assert.NoError(t, err, "converting to eml")
msg, err := api.BytesToMessageable(body)
require.NoError(t, err, "creating message")
eml, err := enmime.ReadEnvelope(strings.NewReader(out))
require.NoError(t, err, "reading created eml")
assert.Equal(t, ptr.Val(msg.GetSubject()), eml.GetHeader("Subject"))
assert.Equal(t, msg.GetSentDateTime().Format(time.RFC1123Z), eml.GetHeader("Date"))
assert.Equal(t, formatAddress(msg.GetFrom().GetEmailAddress()), eml.GetHeader("From"))
ccs := strings.Split(eml.GetHeader("Cc"), ", ")
for _, cc := range msg.GetCcRecipients() {
assert.Contains(t, ccs, formatAddress(cc.GetEmailAddress()))
}
bccs := strings.Split(eml.GetHeader("Bcc"), ", ")
for _, bcc := range msg.GetBccRecipients() {
assert.Contains(t, bccs, formatAddress(bcc.GetEmailAddress()))
}
tos := strings.Split(eml.GetHeader("To"), ", ")
for _, to := range msg.GetToRecipients() {
assert.Contains(t, tos, formatAddress(to.GetEmailAddress()))
}
source := strings.ReplaceAll(eml.HTML, "\n", "")
target := strings.ReplaceAll(ptr.Val(msg.GetBody().GetContent()), "\n", "")
// replace the cid with a constant value to make the comparison
re := regexp.MustCompile(`src="cid:[^"]*"`)
source = re.ReplaceAllString(source, `src="cid:replaced"`)
target = re.ReplaceAllString(target, `src="cid:replaced"`)
assert.Equal(t, source, target)
}
func (suite *EMLUnitSuite) TestConvert_edge_cases() {
tests := []struct {
name string
transform func(models.Messageable)
}{
{
name: "just a name",
transform: func(msg models.Messageable) {
msg.GetFrom().GetEmailAddress().SetName(ptr.To("alphabob"))
msg.GetFrom().GetEmailAddress().SetAddress(nil)
},
},
{
name: "incorrect address",
transform: func(msg models.Messageable) {
msg.GetFrom().GetEmailAddress().SetAddress(ptr.To("invalid"))
},
},
{
name: "empty attachment",
transform: func(msg models.Messageable) {
attachments := msg.GetAttachments()
err := attachments[0].GetBackingStore().Set("contentBytes", []uint8{})
require.NoError(suite.T(), err, "setting attachment content")
},
},
}
for _, test := range tests {
suite.Run(test.name, func() {
t := suite.T()
ctx, flush := tester.NewContext(t)
defer flush()
body := []byte(testdata.EmailWithAttachments)
msg, err := api.BytesToMessageable(body)
require.NoError(t, err, "creating message")
test.transform(msg)
writer := kjson.NewJsonSerializationWriter()
defer writer.Close()
err = writer.WriteObjectValue("", msg)
require.NoError(t, err, "serializing message")
nbody, err := writer.GetSerializedContent()
require.NoError(t, err, "getting serialized content")
_, err = FromJSON(ctx, nbody)
assert.NoError(t, err, "converting to eml")
})
}
}