diff --git a/DNN Platform/Library/Services/Mail/CoreMailProvider.cs b/DNN Platform/Library/Services/Mail/CoreMailProvider.cs index 10aea18e5b8..7d71b865180 100644 --- a/DNN Platform/Library/Services/Mail/CoreMailProvider.cs +++ b/DNN Platform/Library/Services/Mail/CoreMailProvider.cs @@ -8,6 +8,7 @@ namespace DotNetNuke.Services.Mail using System.Linq; using System.Net; using System.Net.Mail; + using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; @@ -77,6 +78,23 @@ public override string SendMail(MailInfo mailInfo, SmtpInfo smtpInfo = null) } } + /// Adds alternate views to the . + /// The message to which the alternate views should be added. + /// The message body. + /// The encoding of the message body. + internal static void AddAlternateView(MailMessage mailMessage, string body, Encoding bodyEncoding) + { + // added support for multipart html messages + // add text part as alternate view + var plainView = AlternateView.CreateAlternateViewFromString(Mail.ConvertToText(body), bodyEncoding, "text/plain"); + mailMessage.AlternateViews.Add(plainView); + if (mailMessage.IsBodyHtml) + { + var htmlView = AlternateView.CreateAlternateViewFromString(body, bodyEncoding, "text/html"); + mailMessage.AlternateViews.Add(htmlView); + } + } + private static string ValidateSmtpInfo(SmtpInfo smtpInfo) { if (smtpInfo != null && !string.IsNullOrEmpty(smtpInfo.Server)) @@ -201,6 +219,9 @@ private static MailMessage CreateMailMessage(MailInfo mailInfo, SmtpInfo smtpInf mailMessage.Subject = HtmlUtils.StripWhiteSpace(mailInfo.Subject, true); mailMessage.BodyEncoding = mailInfo.BodyEncoding; mailMessage.Body = mailInfo.Body; + + AddAlternateView(mailMessage, mailInfo.Body, mailInfo.BodyEncoding); + return mailMessage; } diff --git a/DNN Platform/Tests/DotNetNuke.Tests.Core/Services/Mail/MailTests.cs b/DNN Platform/Tests/DotNetNuke.Tests.Core/Services/Mail/MailTests.cs index 8cfe6bf866e..76e9c56240a 100644 --- a/DNN Platform/Tests/DotNetNuke.Tests.Core/Services/Mail/MailTests.cs +++ b/DNN Platform/Tests/DotNetNuke.Tests.Core/Services/Mail/MailTests.cs @@ -1,45 +1,161 @@ -// -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// -using System; -using NUnit.Framework; - -namespace DotNetNuke.Tests.Core.Services.Mail -{ - [TestFixture] - public class MailTests - { - [Test] - public void ConvertToText_returns_the_input_for_simple_strings() - { - //arrange - Func sut = DotNetNuke.Services.Mail.Mail.ConvertToText; - //act - var result = sut("Hello World"); - //assert - Assert.AreEqual("Hello World", result); - } - [Test] - public void ConvertToText_removes_tags() - { - //arrange - Func sut = DotNetNuke.Services.Mail.Mail.ConvertToText; - //act - var result = sut("

Hello World

"); - //assert - Assert.AreEqual("Hello World", result.Trim()); - } - - [Test] - public void ConvertToText_removes_styles_including_css_defs() - { - //arrange - Func sut = DotNetNuke.Services.Mail.Mail.ConvertToText; - //act - var result = sut("World"); - //assert - Assert.AreEqual("World", result.Trim()); - } - } -} +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information +namespace DotNetNuke.Tests.Core.Services.Mail +{ + using System; + using System.Net.Mail; + using System.Net.Mime; + using System.Text; + + using DotNetNuke.Services.Mail; + using NUnit.Framework; + + [TestFixture] + public class MailTests + { + [Test] + public void ConvertToText_returns_the_input_for_simple_strings() + { + Func sut = DotNetNuke.Services.Mail.Mail.ConvertToText; + var result = sut("Hello World"); + Assert.AreEqual("Hello World", result); + } + + [Test] + public void ConvertToText_removes_tags() + { + Func sut = DotNetNuke.Services.Mail.Mail.ConvertToText; + var result = sut("

Hello World

"); + Assert.AreEqual("Hello World", result.Trim()); + } + + [Test] + public void ConvertToText_removes_styles_including_css_defs() + { + Func sut = DotNetNuke.Services.Mail.Mail.ConvertToText; + var result = sut("World"); + Assert.AreEqual("World", result.Trim()); + } + + [Test] + public void GivenBodyIsNotHtmlWhenAddAlternateViewThenShouldContainsPlainViewOnly() + { + // special character + MailMessage mailMessage = new MailMessage() + { + IsBodyHtml = false + }; + ContentType plain = new ContentType("text/plain") + { + CharSet = "us-ascii" + }; + AlternateView plainView = AlternateView.CreateAlternateViewFromString("body\n", plain); + + CoreMailProvider.AddAlternateView(mailMessage, "body\n", Encoding.ASCII); + + AssertEqualAlternativeView(plainView, mailMessage.AlternateViews[0]); + Assert.AreEqual(1, mailMessage.AlternateViews.Count); + } + + [Test] + public void GivenBodyHtmlWhenAddAlternateViewThenShouldContainsPlainAndHtmlViews() + { + // special character + MailMessage mailMessage = new MailMessage() + { + IsBodyHtml = true + }; + ContentType plain = new ContentType("text/plain") + { + CharSet = "us-ascii" + }; + ContentType html = new ContentType("text/html") + { + CharSet = "us-ascii" + }; + AlternateView plainView = AlternateView.CreateAlternateViewFromString("body\n", plain); + AlternateView htmlView = AlternateView.CreateAlternateViewFromString("body\n", html); + + CoreMailProvider.AddAlternateView(mailMessage, "body\n", Encoding.ASCII); + + AssertEqualAlternativeView(plainView, mailMessage.AlternateViews[0]); + AssertEqualAlternativeView(htmlView, mailMessage.AlternateViews[1]); + Assert.AreEqual(2, mailMessage.AlternateViews.Count); + } + + [Test] + public void GivenEncodingIsAsciiWhenAddAlternateViewThenCharsetShouldAlwaysAscii() + { + // special character + MailMessage mailMessage = new MailMessage() + { + IsBodyHtml = true + }; + ContentType plain = new ContentType("text/plain") + { + CharSet = "us-ascii" + }; + ContentType html = new ContentType("text/html") + { + CharSet = "us-ascii" + }; + + CoreMailProvider.AddAlternateView(mailMessage, "body\n", Encoding.ASCII); + + Assert.AreEqual(plain, mailMessage.AlternateViews[0].ContentType); + Assert.AreEqual(html, mailMessage.AlternateViews[1].ContentType); + + // no special character + mailMessage = new MailMessage() + { + IsBodyHtml = true + }; + + CoreMailProvider.AddAlternateView(mailMessage, "body", Encoding.ASCII); + + Assert.AreEqual(plain, mailMessage.AlternateViews[0].ContentType); + Assert.AreEqual(html, mailMessage.AlternateViews[1].ContentType); + } + + [Test] + public void GivenBodyEncodingIsUTF8WhenAddAlternateViewThenCharsetShouldAwaysUTF8() + { + // special character + MailMessage mailMessage = new MailMessage() + { + IsBodyHtml = true + }; + ContentType plain = new ContentType("text/plain") + { + CharSet = "utf-8" + }; + ContentType html = new ContentType("text/html") + { + CharSet = "utf-8" + }; + + CoreMailProvider.AddAlternateView(mailMessage, "body\n", Encoding.UTF8); + + Assert.AreEqual(plain, mailMessage.AlternateViews[0].ContentType); + Assert.AreEqual(html, mailMessage.AlternateViews[1].ContentType); + + // no special character + mailMessage = new MailMessage() + { + IsBodyHtml = true + }; + + CoreMailProvider.AddAlternateView(mailMessage, "body", Encoding.UTF8); + + Assert.AreEqual(plain, mailMessage.AlternateViews[0].ContentType); + Assert.AreEqual(html, mailMessage.AlternateViews[1].ContentType); + } + + private static void AssertEqualAlternativeView(AlternateView expected, AlternateView actual) + { + Assert.AreEqual(expected.ContentType, actual.ContentType); + Assert.AreEqual(expected.ContentStream, actual.ContentStream); + } + } +}