diff --git a/.travis.yml b/.travis.yml index 8f8874dd6..da9ab1b6c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ language: csharp -dotnet: 1.0.4 +dotnet: 2.1 os: linux dist: trusty mono: latest @@ -24,9 +24,10 @@ before_script: script: - dotnet restore - dotnet build ./src/SendGrid -c Release - - dotnet test ./tests/SendGrid.Tests/SendGrid.Tests.csproj -c Release -f netcoreapp1.0 + - dotnet test ./tests/SendGrid.Tests/SendGrid.Tests.csproj -c Release -f netcoreapp2.0 - ls ./src/SendGrid/bin/Release/net452/ - ls ./src/SendGrid/bin/Release/netstandard1.3/ + - ls ./src/SendGrid/bin/Release/netstandard2.0/ - dotnet pack ./src/SendGrid -c Release - curl -s https://codecov.io/bash > .codecov - chmod +x .codecov diff --git a/src/SendGrid/Helpers/Mail/MailMessageExtensions.cs b/src/SendGrid/Helpers/Mail/MailMessageExtensions.cs new file mode 100644 index 000000000..265927d9f --- /dev/null +++ b/src/SendGrid/Helpers/Mail/MailMessageExtensions.cs @@ -0,0 +1,137 @@ +// +// Copyright (c) SendGrid. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// +#if NETSTANDARD2_0 || NET452 + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Mail; + +namespace SendGrid.Helpers.Mail +{ + /// + /// A collection of extension to assist with the conversion of System.Net.Mail.MailMessage to + /// + public static class MailMessageExtensions + { + /// + /// Converts a System.Net.Mail.MailAddress to a sendgrid address + /// + /// The address to be converted + /// The result of the conversion + public static EmailAddress ToSendGridAddress(this MailAddress address) + { + return string.IsNullOrWhiteSpace(address.DisplayName) ? + new EmailAddress(address.Address) : + new EmailAddress(address.Address, address.DisplayName.Replace(",", string.Empty).Replace(";", string.Empty)); + } + + /// + /// Copies the attachment from a MailMessage into the object as a base64 string. + /// + /// The attachment to be converted + /// Returns a + public static SendGrid.Helpers.Mail.Attachment ToSendGridAttachment(this System.Net.Mail.Attachment attachment) + { + using (var stream = new MemoryStream()) + { + attachment.ContentStream.CopyTo(stream); + return new SendGrid.Helpers.Mail.Attachment() + { + Disposition = "attachment", + Type = attachment.ContentType.MediaType, + Filename = attachment.Name, + ContentId = attachment.ContentId, + Content = Convert.ToBase64String(stream.ToArray()) + }; + } + } + + /// + /// Converts a System.Net.Mail.MailMessage to a SendGrid message. + /// + /// The MailMessage to be converted + /// Returns a with the properties from the MailMessage + public static SendGridMessage ToSendGridMessage(this MailMessage message) + { + var sendgridMessage = new SendGridMessage(); + + sendgridMessage.From = ToSendGridAddress(message.From); + + if (message.ReplyToList.Any()) + { + if (message.ReplyToList.Count > 1) + { + throw new ArgumentException("Sendgrid only supports one reply to address."); + } + + sendgridMessage.ReplyTo = message.ReplyToList.Single().ToSendGridAddress(); + } + + if (message.To.Any()) + { + var tos = message.To.Select(ToSendGridAddress).ToList(); + sendgridMessage.AddTos(tos); + } + + if (message.CC.Any()) + { + var cc = message.CC.Select(ToSendGridAddress).ToList(); + sendgridMessage.AddCcs(cc); + } + + if (message.Bcc.Any()) + { + var bcc = message.Bcc.Select(ToSendGridAddress).ToList(); + sendgridMessage.AddBccs(bcc); + } + + if (!string.IsNullOrWhiteSpace(message.Subject)) + { + sendgridMessage.Subject = message.Subject; + } + + if (message.Headers.Count > 0) + { + var headers = message.Headers.AllKeys.ToDictionary(x => x, x => message.Headers[x]); + sendgridMessage.AddHeaders(headers); + } + + if (!string.IsNullOrWhiteSpace(message.Body)) + { + var content = message.Body; + + if (message.IsBodyHtml) + { + + if (content.StartsWith("{message.Body}"; + } + + sendgridMessage.AddContent("text/html", content); + } + else + { + sendgridMessage.AddContent("text/plain", content); + } + } + + if (message.Attachments.Any()) + { + sendgridMessage.Attachments = new List(); + sendgridMessage.Attachments.AddRange(message.Attachments.Select(ToSendGridAttachment)); + } + + return sendgridMessage; + } + } +} +#endif diff --git a/tests/SendGrid.Tests/Helpers/Mail/MailMessageExtensionsTests.cs b/tests/SendGrid.Tests/Helpers/Mail/MailMessageExtensionsTests.cs new file mode 100644 index 000000000..fc1117648 --- /dev/null +++ b/tests/SendGrid.Tests/Helpers/Mail/MailMessageExtensionsTests.cs @@ -0,0 +1,105 @@ +using System.IO; +using System.Linq; +using System.Net.Mail; +using SendGrid.Helpers.Mail; +using Xunit; + +namespace SendGrid.Tests.Helpers.Mail +{ + public class MailMessageExtensionsTests + { + [Theory] + [InlineData("Example@example.com")] + [InlineData("Example+data@example.com")] + public void ConvertEmailAddresses(string email) + { + var address = new MailAddress(email).ToSendGridAddress(); + Assert.Equal(email, address.Email); + } + + [Theory] + [InlineData("Example@example.com", "Ben@example.com", "Widget Factory Production", "Ben, widget production is down 15%, could you investigate?")] + public void TestSimpleMailMessageEmail(string from, string to, string subject, string body) + { + var mail = new MailMessage(from, to) + { + Subject = subject, + + }; + + mail.Body = body; + + var message = mail.ToSendGridMessage(); + + Assert.Equal(from, message.From.Email); + Assert.Equal(subject, message.Subject); + Assert.Contains(message.Personalizations.SelectMany(x => x.Tos), x => x.Email == to); + Assert.Contains(message.Contents, x => x.Value == body); + } + + [Theory] + [InlineData("Example@example.com", "Ben@example.com", "Widget Factory Production", "Management@example.com", "HR@example.com")] + public void TestMailMessageEmailWithCC(string from, string to, string subject, string cc, string bcc) + { + var mail = new MailMessage(from, to) + { + Subject = subject + }; + + mail.CC.Add(cc); + mail.Bcc.Add(bcc); + + var message = mail.ToSendGridMessage(); + + + Assert.Equal(from, message.From.Email); + Assert.Equal(subject, message.Subject); + Assert.Contains(message.Personalizations.SelectMany(x => x.Tos), x => x.Email == to); + Assert.Contains(message.Personalizations.SelectMany(x => x.Ccs), x => x.Email == cc); + Assert.Contains(message.Personalizations.SelectMany(x => x.Bccs), x => x.Email == bcc); + } + + [Theory] + [InlineData("Example@example.com", "Ben@example.com", "invoicing@example.com")] + public void TestSimpleMailMessageReplyTo(string from, string to, string replyTo) + { + var mail = new MailMessage(from, to); + mail.ReplyToList.Add(replyTo); + + var message = mail.ToSendGridMessage(); + + Assert.Equal(replyTo, message.ReplyTo.Email); + } + + [Fact] + public void TestMailMessageShouldConvertAttachements() + { + var mail = new MailMessage("Ben@Example.com", "HR@Example.com"); + var data = new byte[] { 0x1, 0x2, 0x3, 0x4 }; + + SendGridMessage message = null; + + using (var stream = new MemoryStream(data)) + { + mail.Attachments.Add(new System.Net.Mail.Attachment(stream, "Example.pdf")); + message = mail.ToSendGridMessage(); + } + + Assert.NotEmpty(message.Attachments); + var attachment = message.Attachments.Single(); + Assert.Equal("Example.pdf", attachment.Filename); + Assert.False(string.IsNullOrEmpty(attachment.Content)); + } + + [Fact] + public void TestMailMessageHeaderConverted() + { + var mail = new MailMessage("Ben@Example.com", "HR@Example.com"); + mail.Headers.Add("Example", "Example"); + + var message = mail.ToSendGridMessage(); + var headers = message.Personalizations.SelectMany(x => x.Headers); + Assert.Contains(headers, x => x.Key == "Example" && x.Value == "Example"); + } + } +} diff --git a/tests/SendGrid.Tests/SendGrid.Tests.csproj b/tests/SendGrid.Tests/SendGrid.Tests.csproj index b76f91437..a810e8027 100644 --- a/tests/SendGrid.Tests/SendGrid.Tests.csproj +++ b/tests/SendGrid.Tests/SendGrid.Tests.csproj @@ -1,11 +1,11 @@  - netcoreapp1.0 + netcoreapp2.0 SendGrid.Tests SendGrid.Tests true - 1.0.4 + 2.0.9 false false false