diff --git a/.github/workflows/dotnet-core.yml b/.github/workflows/dotnet-core.yml index f3c2b56..091598b 100644 --- a/.github/workflows/dotnet-core.yml +++ b/.github/workflows/dotnet-core.yml @@ -2,7 +2,7 @@ name: Build & Test on: pull_request: - branches: [master] + branches: [main] jobs: build: diff --git a/.gitignore b/.gitignore index c72a37e..7d9fe0a 100644 --- a/.gitignore +++ b/.gitignore @@ -246,3 +246,5 @@ ModelManifest.xml # Verify test files *.received.txt + +.env diff --git a/FluentEmail.sln b/FluentEmail.sln index 10d31e5..e13c173 100644 --- a/FluentEmail.sln +++ b/FluentEmail.sln @@ -4,6 +4,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00 VisualStudioVersion = 17.4.33205.214 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{6DC215BD-05EF-49A6-ADBE-8AE399952EEC}" + ProjectSection(SolutionItems) = preProject + test\Directory.Build.props = test\Directory.Build.props + EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{D5C44238-0312-43F8-9705-EACFB039A48C}" EndProject diff --git a/FluentEmail.sln.DotSettings b/FluentEmail.sln.DotSettings new file mode 100644 index 0000000..248dd01 --- /dev/null +++ b/FluentEmail.sln.DotSettings @@ -0,0 +1,4 @@ + + True + True + True \ No newline at end of file diff --git a/src/FluentEmail.Core/FluentEmail.Core.csproj b/src/FluentEmail.Core/FluentEmail.Core.csproj index 5bba4ed..645edc1 100644 --- a/src/FluentEmail.Core/FluentEmail.Core.csproj +++ b/src/FluentEmail.Core/FluentEmail.Core.csproj @@ -20,7 +20,7 @@ - + diff --git a/src/Senders/FluentEmail.Mailtrap/MailtrapSender.cs b/src/Senders/FluentEmail.Mailtrap/MailtrapSender.cs index 1e8484c..989364e 100644 --- a/src/Senders/FluentEmail.Mailtrap/MailtrapSender.cs +++ b/src/Senders/FluentEmail.Mailtrap/MailtrapSender.cs @@ -19,10 +19,10 @@ namespace FluentEmail.Mailtrap /// public class MailtrapSender : IMailtrapSender, IDisposable { - private const string URL = "https://send.api.mailtrap.io/api/send"; private readonly SmtpClient _smtpClient; private static readonly int[] ValidPorts = {25,587, 2525}; private readonly string _apiKey; + private readonly string _apiHost; /// /// Creates a sender that uses the given Mailtrap credentials, but does not dispose it. @@ -31,7 +31,7 @@ public class MailtrapSender : IMailtrapSender, IDisposable /// Password of your mailtrap.io SMTP inbox /// Host address for the Mailtrap.io SMTP inbox /// Port for the Mailtrap.io SMTP server. Accepted values are 25, 465 or 2525. - public MailtrapSender(string userName, string password, string host = "smtp.mailtrap.io", int? port = null) + public MailtrapSender(string userName, string password, string host = "smtp.mailtrap.io", int? port = null, string apiHost = "https://send.api.mailtrap.io/api/send") { if (string.IsNullOrWhiteSpace(userName)) throw new ArgumentException("Mailtrap UserName needs to be supplied", nameof(userName)); @@ -42,6 +42,7 @@ public MailtrapSender(string userName, string password, string host = "smtp.mail if (port.HasValue && !ValidPorts.Contains(port.Value)) throw new ArgumentException("Mailtrap Port needs to be either 25, 465 or 2525", nameof(port)); _apiKey = password; + _apiHost = apiHost; _smtpClient = new SmtpClient(host, port.GetValueOrDefault(587)) { Credentials = new NetworkCredential(userName, password), @@ -66,12 +67,12 @@ public Task SendAsync(IFluentEmail email, CancellationToken? token public async Task SendWithTemplateAsync(IFluentEmail email, string templateName, object templateData, CancellationToken? token = null) { token?.ThrowIfCancellationRequested(); - using (var httpClient = new HttpClient { BaseAddress = new Uri(URL) }) + using (var httpClient = new HttpClient { BaseAddress = new Uri(_apiHost) }) { httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _apiKey); httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); var jsonContent = HttpClientHelpers.GetJsonBody(BuildMailtrapParameters(email, templateName, templateData)); - var response = await httpClient.Post(URL, jsonContent); + var response = await httpClient.Post(_apiHost, jsonContent); var result = new SendResponse { MessageId = response.Data?.Id }; if (!response.Success) { diff --git a/test/Directory.Build.props b/test/Directory.Build.props index dc6b5a1..5cde688 100644 --- a/test/Directory.Build.props +++ b/test/Directory.Build.props @@ -4,11 +4,10 @@ false true net8.0 - Exe - + runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/FluentEmail.Bootstrap.Tests/BootstrapTests.cs b/test/FluentEmail.Bootstrap.Tests/BootstrapTests.cs index cea8e5d..5660afd 100644 --- a/test/FluentEmail.Bootstrap.Tests/BootstrapTests.cs +++ b/test/FluentEmail.Bootstrap.Tests/BootstrapTests.cs @@ -4,6 +4,7 @@ using System; using System.Threading.Tasks; using FluentEmail.Core; +using FluentEmail.Core.Interfaces; using FluentEmail.Liquid; using Fluid; using Microsoft.Extensions.FileProviders; @@ -25,11 +26,9 @@ public BootstrapTests() { _settings.ScrubLinesContaining("Compiled with Bootstrap Email DotNet"); _settings.DisableDiff(); - // default to have no file provider, only required when layout files are in use - SetupRenderer(); } - private static void SetupRenderer( + private static ITemplateRenderer SetupRenderer( IFileProvider fileProvider = null, Action configureTemplateContext = null) { @@ -38,7 +37,7 @@ private static void SetupRenderer( FileProvider = fileProvider, ConfigureTemplateContext = configureTemplateContext, }; - Email.DefaultRenderer = new LiquidRenderer(Options.Create(options)); + return new LiquidRenderer(Options.Create(options)); } [Fact] @@ -51,11 +50,13 @@ public Task CompileBootstrap_Compiles() """; - var email = Email - .From(FromEmail) + var email = new Email(FromEmail) + { + Renderer = SetupRenderer() + } .To(ToEmail) .Subject(Subject) - .UsingTemplate(template, new ViewModel { Name = "LUKE", Numbers = new[] { "1", "2", "3" } }) + .UsingTemplate(template, new ViewModel { Name = "LUKE", Numbers = ["1", "2", "3"] }) .CompileBootstrap(); return Verifier.Verify(email.Data.Body, _settings); @@ -71,8 +72,10 @@ public Task UsingBootstrapBody_Compiles() """; - var email = Email - .From(FromEmail) + var email = new Email(FromEmail) + { + Renderer = SetupRenderer() + } .To(ToEmail) .Subject(Subject) .UsingBootstrapBody(body); @@ -91,11 +94,13 @@ public Task UsingBootstrapTemplate_Compiles() """; - var email = Email - .From(FromEmail) + var email = new Email(FromEmail) + { + Renderer = SetupRenderer() + } .To(ToEmail) .Subject(Subject) - .UsingBootstrapTemplate(template, new ViewModel { Name = "LUKE", Numbers = new[] { "1", "2", "3" } }); + .UsingBootstrapTemplate(template, new ViewModel { Name = "LUKE", Numbers = ["1", "2", "3"] }); return Verifier.Verify(email.Data.Body, _settings); } diff --git a/test/FluentEmail.Bootstrap.Tests/FluentEmail.Bootstrap.Tests.csproj b/test/FluentEmail.Bootstrap.Tests/FluentEmail.Bootstrap.Tests.csproj index bf07630..5b34b26 100644 --- a/test/FluentEmail.Bootstrap.Tests/FluentEmail.Bootstrap.Tests.csproj +++ b/test/FluentEmail.Bootstrap.Tests/FluentEmail.Bootstrap.Tests.csproj @@ -1,9 +1,7 @@  - net8.0 true - preview @@ -12,10 +10,9 @@ - + - - + - + diff --git a/test/FluentEmail.Core.Tests/.env.sample b/test/FluentEmail.Core.Tests/.env.sample new file mode 100644 index 0000000..c0c2e14 --- /dev/null +++ b/test/FluentEmail.Core.Tests/.env.sample @@ -0,0 +1,39 @@ +FE_TEST_TO_EMAIL= +FE_TEST_FROM_EMAIL= + +# MailTrap Tests Credentials +FE_TEST_MAILTRAP_TO_EMAIL= +FE_TEST_MAILTRAP_FROM_EMAIL= +FE_TEST_MAILTRAP_HOST= +FE_TEST_MAILTRAP_USER= +FE_TEST_MAILTRAP_PWD= +FE_TEST_MAILTRAP_PORT=587 +FE_TEST_MAILTRAP_API_HOST= +FE_TEST_MAILTRAP_API_KEY= +FE_TEST_MAILTRAP_TEMPLATE= + +# MailGun Tests Credentials +FE_TEST_MAILGUN_TO_EMAIL= +FE_TEST_MAILGUN_FROM_EMAIL= +FE_TEST_MAILGUN_DOMAIN= +FE_TEST_MAILGUN_API_KEY= + +# Azure Email Service Credentials +FE_TEST_AZURE_TO_EMAIL= +FE_TEST_AZURE_FROM_EMAIL= +FE_TEST_AZURE_API_HOST= + +# Postmark Credentials +FE_TEST_POSTMARK_API_KEY= +FE_TEST_POSTMARK_FROM_EMAIL= + +# SendGrid Credentials +FE_TEST_SENDGRID_API_KEY= +FE_TEST_SENDGRID_TEMPLATE= + +# Graph Credentials +FE_TEST_GRAPH_TO_EMAIL= +FE_TEST_GRAPH_FROM_EMAIL= +FE_TEST_GRAPH_TENANT_ID= +FE_TEST_GRAPH_APP_ID= +FE_TEST_GRAPH_CLIENT_SECRET= diff --git a/test/FluentEmail.Core.Tests/AddressTests.cs b/test/FluentEmail.Core.Tests/AddressTests.cs index ee37960..ca651cd 100644 --- a/test/FluentEmail.Core.Tests/AddressTests.cs +++ b/test/FluentEmail.Core.Tests/AddressTests.cs @@ -1,107 +1,103 @@ -using Xunit; -using AwesomeAssertions; +namespace FluentEmail.Core.Tests; -namespace FluentEmail.Core.Tests +public class AddressTests { - public class AddressTests - { - [Fact] - public void SplitAddress_Test() - { - var email = Email - .From("test@test.com") - .To("james@test.com;john@test.com", "James 1;John 2"); - - email.Data.ToAddresses.Count.Should().Be(2); - email.Data.ToAddresses[0].EmailAddress.Should().Be("james@test.com"); - email.Data.ToAddresses[1].EmailAddress.Should().Be("john@test.com"); - email.Data.ToAddresses[0].Name.Should().Be("James 1"); - email.Data.ToAddresses[1].Name.Should().Be("John 2"); - } - - [Fact] - public void SplitAddress_Test2() - { - var email = Email - .From("test@test.com") - .To("james@test.com; john@test.com", "James 1"); - - email.Data.ToAddresses.Count.Should().Be(2); - email.Data.ToAddresses[0].EmailAddress.Should().Be("james@test.com"); - email.Data.ToAddresses[1].EmailAddress.Should().Be("john@test.com"); - email.Data.ToAddresses[0].Name.Should().Be("James 1"); - email.Data.ToAddresses[1].Name.Should().Be(string.Empty); - } - - [Fact] - public void SplitAddress_Test3() - { - var email = Email - .From("test@test.com") - .To("james@test.com; john@test.com; Fred@test.com", "James 1;;Fred"); - - email.Data.ToAddresses.Count.Should().Be(3); - email.Data.ToAddresses[0].EmailAddress.Should().Be("james@test.com"); - email.Data.ToAddresses[1].EmailAddress.Should().Be("john@test.com"); - email.Data.ToAddresses[2].EmailAddress.Should().Be("Fred@test.com"); - email.Data.ToAddresses[0].Name.Should().Be("James 1"); - email.Data.ToAddresses[1].Name.Should().Be(string.Empty); - email.Data.ToAddresses[2].Name.Should().Be("Fred"); - } - - [Fact] - public void SetFromAddress() - { - var email = new Email(); - email.SetFrom("test@test.test", "test"); - - email.Data.FromAddress.EmailAddress.Should().Be("test@test.test"); - email.Data.FromAddress.Name.Should().Be("test"); - } - - #region Refactored tests using setup through constructor. - [Fact] - public void New_SplitAddress_Test() - { - var email = new Email() - .To("james@test.com;john@test.com", "James 1;John 2"); - - email.Data.ToAddresses.Count.Should().Be(2); - email.Data.ToAddresses[0].EmailAddress.Should().Be("james@test.com"); - email.Data.ToAddresses[1].EmailAddress.Should().Be("john@test.com"); - email.Data.ToAddresses[0].Name.Should().Be("James 1"); - email.Data.ToAddresses[1].Name.Should().Be("John 2"); - } - - - [Fact] - public void New_SplitAddress_Test2() - { - var email = new Email() - .To("james@test.com; john@test.com", "James 1"); - - email.Data.ToAddresses.Count.Should().Be(2); - email.Data.ToAddresses[0].EmailAddress.Should().Be("james@test.com"); - email.Data.ToAddresses[1].EmailAddress.Should().Be("john@test.com"); - email.Data.ToAddresses[0].Name.Should().Be("James 1"); - email.Data.ToAddresses[1].Name.Should().Be(string.Empty); - } - - - [Fact] - public void New_SplitAddress_Test3() - { - var email = new Email() - .To("james@test.com; john@test.com; Fred@test.com", "James 1;;Fred"); - - email.Data.ToAddresses.Count.Should().Be(3); - email.Data.ToAddresses[0].EmailAddress.Should().Be("james@test.com"); - email.Data.ToAddresses[1].EmailAddress.Should().Be("john@test.com"); - email.Data.ToAddresses[2].EmailAddress.Should().Be("Fred@test.com"); - email.Data.ToAddresses[0].Name.Should().Be("James 1"); - email.Data.ToAddresses[1].Name.Should().Be(string.Empty); - email.Data.ToAddresses[2].Name.Should().Be("Fred"); - } - #endregion - } -} + [Fact] + public void SplitAddress_Test() + { + var email = Email + .From("test@test.com") + .To("james@test.com;john@test.com", "James 1;John 2"); + + email.Data.ToAddresses.Count.Should().Be(2); + email.Data.ToAddresses[0].EmailAddress.Should().Be("james@test.com"); + email.Data.ToAddresses[1].EmailAddress.Should().Be("john@test.com"); + email.Data.ToAddresses[0].Name.Should().Be("James 1"); + email.Data.ToAddresses[1].Name.Should().Be("John 2"); + } + + [Fact] + public void SplitAddress_Test2() + { + var email = Email + .From("test@test.com") + .To("james@test.com; john@test.com", "James 1"); + + email.Data.ToAddresses.Count.Should().Be(2); + email.Data.ToAddresses[0].EmailAddress.Should().Be("james@test.com"); + email.Data.ToAddresses[1].EmailAddress.Should().Be("john@test.com"); + email.Data.ToAddresses[0].Name.Should().Be("James 1"); + email.Data.ToAddresses[1].Name.Should().Be(string.Empty); + } + + [Fact] + public void SplitAddress_Test3() + { + var email = Email + .From("test@test.com") + .To("james@test.com; john@test.com; Fred@test.com", "James 1;;Fred"); + + email.Data.ToAddresses.Count.Should().Be(3); + email.Data.ToAddresses[0].EmailAddress.Should().Be("james@test.com"); + email.Data.ToAddresses[1].EmailAddress.Should().Be("john@test.com"); + email.Data.ToAddresses[2].EmailAddress.Should().Be("Fred@test.com"); + email.Data.ToAddresses[0].Name.Should().Be("James 1"); + email.Data.ToAddresses[1].Name.Should().Be(string.Empty); + email.Data.ToAddresses[2].Name.Should().Be("Fred"); + } + + [Fact] + public void SetFromAddress() + { + var email = new Email(); + email.SetFrom("test@test.test", "test"); + + email.Data.FromAddress.EmailAddress.Should().Be("test@test.test"); + email.Data.FromAddress.Name.Should().Be("test"); + } + + #region Refactored tests using setup through constructor. + [Fact] + public void New_SplitAddress_Test() + { + var email = new Email() + .To("james@test.com;john@test.com", "James 1;John 2"); + + email.Data.ToAddresses.Count.Should().Be(2); + email.Data.ToAddresses[0].EmailAddress.Should().Be("james@test.com"); + email.Data.ToAddresses[1].EmailAddress.Should().Be("john@test.com"); + email.Data.ToAddresses[0].Name.Should().Be("James 1"); + email.Data.ToAddresses[1].Name.Should().Be("John 2"); + } + + + [Fact] + public void New_SplitAddress_Test2() + { + var email = new Email() + .To("james@test.com; john@test.com", "James 1"); + + email.Data.ToAddresses.Count.Should().Be(2); + email.Data.ToAddresses[0].EmailAddress.Should().Be("james@test.com"); + email.Data.ToAddresses[1].EmailAddress.Should().Be("john@test.com"); + email.Data.ToAddresses[0].Name.Should().Be("James 1"); + email.Data.ToAddresses[1].Name.Should().Be(string.Empty); + } + + + [Fact] + public void New_SplitAddress_Test3() + { + var email = new Email() + .To("james@test.com; john@test.com; Fred@test.com", "James 1;;Fred"); + + email.Data.ToAddresses.Count.Should().Be(3); + email.Data.ToAddresses[0].EmailAddress.Should().Be("james@test.com"); + email.Data.ToAddresses[1].EmailAddress.Should().Be("john@test.com"); + email.Data.ToAddresses[2].EmailAddress.Should().Be("Fred@test.com"); + email.Data.ToAddresses[0].Name.Should().Be("James 1"); + email.Data.ToAddresses[1].Name.Should().Be(string.Empty); + email.Data.ToAddresses[2].Name.Should().Be("Fred"); + } + #endregion +} \ No newline at end of file diff --git a/test/FluentEmail.Core.Tests/AttachmentTests.cs b/test/FluentEmail.Core.Tests/AttachmentTests.cs index 6ba2918..e57bdc7 100644 --- a/test/FluentEmail.Core.Tests/AttachmentTests.cs +++ b/test/FluentEmail.Core.Tests/AttachmentTests.cs @@ -1,62 +1,52 @@ -using System.IO; -using System.Linq; -using System.Reflection; -using FluentEmail.Core.Models; -using Xunit; -using AwesomeAssertions; - -namespace FluentEmail.Core.Tests + +namespace FluentEmail.Core.Tests; + +public class AttachmentTests { - public class AttachmentTests - { - private Assembly ThisAssembly() => this.GetType().GetTypeInfo().Assembly; - const string toEmail = "bob@test.com"; - const string fromEmail = "johno@test.com"; - const string subject = "sup dawg"; + private const string ToEmail = "bob@test.com"; + private const string FromEmail = "johno@test.com"; + private const string Subject = "sup dawg"; - [Fact] - public void Attachment_from_stream_Is_set() - { - using (var stream = File.OpenRead($"{Path.Combine(Directory.GetCurrentDirectory(), "test.txt")}")) - { - var attachment = new Attachment - { - Data = stream, - Filename = "Test.txt", - ContentType = "text/plain" - }; - - var email = Email.From(fromEmail) - .To(toEmail) - .Subject(subject) - .Attach(attachment); - - email.Data.Attachments.First().Data.Length.Should().Be(20); - } - } - - [Fact] - public void Attachment_from_filename_Is_set() + [Fact] + public void Attachment_from_stream_Is_set() + { + using var stream = File.OpenRead($"{Path.Combine(Directory.GetCurrentDirectory(), "test.txt")}"); + var attachment = new Attachment { - var email = Email.From(fromEmail) - .To(toEmail) - .Subject(subject) - .AttachFromFilename($"{Path.Combine(Directory.GetCurrentDirectory(), "test.txt")}", "text/plain"); + Data = stream, + Filename = "Test.txt", + ContentType = "text/plain" + }; - email.Data.Attachments.First().Data.Length.Should().Be(20); - } + var email = Email.From(FromEmail) + .To(ToEmail) + .Subject(Subject) + .Attach(attachment); - [Fact] - public void Attachment_from_filename_AttachmentName_Is_set() - { - var attachmentName = "attachment.txt"; - var email = Email.From(fromEmail) - .To(toEmail) - .Subject(subject) - .AttachFromFilename($"{Path.Combine(Directory.GetCurrentDirectory(), "test.txt")}", "text/plain", attachmentName); - - email.Data.Attachments.First().Data.Length.Should().Be(20); - email.Data.Attachments.First().Filename.Should().Be(attachmentName); - } + email.Data.Attachments.First().Data.Length.Should().Be(20); + } + + [Fact] + public void Attachment_from_filename_Is_set() + { + var email = Email.From(FromEmail) + .To(ToEmail) + .Subject(Subject) + .AttachFromFilename($"{Path.Combine(Directory.GetCurrentDirectory(), "test.txt")}", "text/plain"); + + email.Data.Attachments.First().Data.Length.Should().Be(20); + } + + [Fact] + public void Attachment_from_filename_AttachmentName_Is_set() + { + var attachmentName = "attachment.txt"; + var email = Email.From(FromEmail) + .To(ToEmail) + .Subject(Subject) + .AttachFromFilename($"{Path.Combine(Directory.GetCurrentDirectory(), "test.txt")}", "text/plain", attachmentName); + + email.Data.Attachments.First().Data.Length.Should().Be(20); + email.Data.Attachments.First().Filename.Should().Be(attachmentName); } -} +} \ No newline at end of file diff --git a/test/FluentEmail.Core.Tests/AzureEmailSenderTests.cs b/test/FluentEmail.Core.Tests/AzureEmailSenderTests.cs deleted file mode 100644 index 21b046b..0000000 --- a/test/FluentEmail.Core.Tests/AzureEmailSenderTests.cs +++ /dev/null @@ -1,126 +0,0 @@ -using System; -using System.IO; -using System.Threading.Tasks; -using Xunit; -using AwesomeAssertions; -using Attachment = FluentEmail.Core.Models.Attachment; - -namespace FluentEmail.Azure.Email.Tests -{ - [Collection("NonParallel")] - public class AzureEmailSenderTests - { - const string connectionString = ""; // TODO: Put your ConnectionString here - - const string toEmail = "fluentEmail@mailinator.com"; - const string toName = "FluentEmail Mailinator"; - const string fromEmail = "test@fluentmail.com"; // TODO: Put a valid/verified sender here - const string fromName = "AzureEmailSender Test"; - - public AzureEmailSenderTests() - { - if (string.IsNullOrWhiteSpace(connectionString)) throw new ArgumentException("Azure Communication Services Connection String needs to be supplied"); - - var sender = new AzureEmailSender(connectionString); - Core.Email.DefaultSender = sender; - } - - [Fact(Skip="No azure credentials")] - public async Task CanSendEmail() - { - const string subject = "SendMail Test"; - const string body = "This email is testing send mail functionality of Azure Email Sender."; - - var email = Core.Email - .From(fromEmail, fromName) - .To(toEmail, toName) - .Subject(subject) - .Body(body); - - var response = await email.SendAsync(); - - (response.Successful).Should().BeTrue(); - } - - [Fact(Skip="No azure credentials")] - public async Task CanSendEmailWithReplyTo() - { - const string subject = "SendMail Test"; - const string body = "This email is testing send mail with ReplyTo functionality of Azure Email Sender."; - - var email = Core.Email - .From(fromEmail, fromName) - .To(toEmail, toName) - .ReplyTo(toEmail, toName) - .Subject(subject) - .Body(body); - - var response = await email.SendAsync(); - - (response.Successful).Should().BeTrue(); - } - - [Fact(Skip="No azure credentials")] - public async Task CanSendEmailWithAttachments() - { - const string subject = "SendMail With Attachments Test"; - const string body = "This email is testing the attachment functionality of Azure Email Sender."; - - await using var stream = File.OpenRead($"{Directory.GetCurrentDirectory()}/test-binary.xlsx"); - var attachment = new Attachment - { - Data = stream, - ContentType = "xlsx", - Filename = "test-binary.xlsx" - }; - - var email = Core.Email - .From(fromEmail, fromName) - .To(toEmail, toName) - .Subject(subject) - .Body(body) - .Attach(attachment); - - - var response = await email.SendAsync(); - - (response.Successful).Should().BeTrue(); - } - - [Fact(Skip="No azure credentials")] - public async Task CanSendHighPriorityEmail() - { - const string subject = "SendMail Test"; - const string body = "This email is testing send mail functionality of Azure Email Sender."; - - var email = Core.Email - .From(fromEmail, fromName) - .To(toEmail, toName) - .Subject(subject) - .Body(body) - .HighPriority(); - - var response = await email.SendAsync(); - - (response.Successful).Should().BeTrue(); - } - - [Fact(Skip="No azure credentials")] - public async Task CanSendLowPriorityEmail() - { - const string subject = "SendMail Test"; - const string body = "This email is testing send mail functionality of Azure Email Sender."; - - var email = Core.Email - .From(fromEmail, fromName) - .To(toEmail, toName) - .Subject(subject) - .Body(body) - .LowPriority(); - - var response = await email.SendAsync(); - - (response.Successful).Should().BeTrue(); - } - } -} diff --git a/test/FluentEmail.Core.Tests/FluentEmail.Core.Tests.csproj b/test/FluentEmail.Core.Tests/FluentEmail.Core.Tests.csproj index cff122f..ad32396 100644 --- a/test/FluentEmail.Core.Tests/FluentEmail.Core.Tests.csproj +++ b/test/FluentEmail.Core.Tests/FluentEmail.Core.Tests.csproj @@ -1,10 +1,5 @@  - - net8.0 - true - - @@ -30,13 +25,19 @@ + + + PreserveNewest + + + PreserveNewest + PreserveNewest PreserveNewest - diff --git a/test/FluentEmail.Core.Tests/FluentEmailTests.cs b/test/FluentEmail.Core.Tests/FluentEmailTests.cs index 8cf5f91..1f6a29c 100644 --- a/test/FluentEmail.Core.Tests/FluentEmailTests.cs +++ b/test/FluentEmail.Core.Tests/FluentEmailTests.cs @@ -1,309 +1,320 @@ using System.Collections.Generic; -using FluentEmail.Core.Models; -using Xunit; -using AwesomeAssertions; -using System.Linq; -namespace FluentEmail.Core.Tests +namespace FluentEmail.Core.Tests; + +public class FluentEmailTests { - public class FluentEmailTests - { - const string toEmail = "bob@test.com"; - const string fromEmail = "johno@test.com"; - const string subject = "sup dawg"; - const string body = "what be the hipitity hap?"; - - [Fact] - public void To_Address_Is_Set() - { - var email = Email - .From(fromEmail) - .To(toEmail); - - email.Data.ToAddresses[0].EmailAddress.Should().Be(toEmail); - } - - [Fact] - public void From_Address_Is_Set() - { - var email = Email.From(fromEmail); - - email.Data.FromAddress.EmailAddress.Should().Be(fromEmail); - } - - [Fact] - public void Subject_Is_Set() - { - var email = Email - .From(fromEmail) - .Subject(subject); - - email.Data.Subject.Should().Be(subject); - } - - [Fact] - public void Body_Is_Set() - { - var email = Email.From(fromEmail) - .Body(body); - - email.Data.Body.Should().Be(body); - } - - [Fact] - public void Can_Add_Multiple_Recipients() - { - string toEmail1 = "bob@test.com"; - string toEmail2 = "ratface@test.com"; - - var email = Email - .From(fromEmail) - .To(toEmail1) - .To(toEmail2); - - email.Data.ToAddresses.Count.Should().Be(2); - } - - [Fact] - public void Can_Add_Multiple_Recipients_From_List() - { - var emails = new List
(); - emails.Add(new Address("email1@email.com")); - emails.Add(new Address("email2@email.com")); - - var email = Email - .From(fromEmail) - .To(emails); - - email.Data.ToAddresses.Count.Should().Be(2); - } - - [Fact] - public void Can_Add_Mutlitple_Recipients_From_String_List() + private const string ToEmail = "bob@test.com"; + private const string FromEmail = "johno@test.com"; + private const string Subject = "sup dawg"; + private const string Body = "what be the hipitity hap?"; + + [Fact] + public void To_Address_Is_Set() + { + var email = Email + .From(FromEmail) + .To(ToEmail); + + email.Data.ToAddresses[0].EmailAddress.Should().Be(ToEmail); + } + + [Fact] + public void From_Address_Is_Set() + { + var email = Email.From(FromEmail); + + email.Data.FromAddress.EmailAddress.Should().Be(FromEmail); + } + + [Fact] + public void Subject_Is_Set() + { + var email = Email + .From(FromEmail) + .Subject(Subject); + + email.Data.Subject.Should().Be(Subject); + } + + [Fact] + public void Body_Is_Set() + { + var email = Email.From(FromEmail) + .Body(Body); + + email.Data.Body.Should().Be(Body); + } + + [Fact] + public void Can_Add_Multiple_Recipients() + { + var toEmail1 = "bob@test.com"; + var toEmail2 = "ratface@test.com"; + + var email = Email + .From(FromEmail) + .To(toEmail1) + .To(toEmail2); + + email.Data.ToAddresses.Count.Should().Be(2); + } + + [Fact] + public void Can_Add_Multiple_Recipients_From_List() + { + var emails = new List
{ - var emails = new List(); - emails.Add("email1@email.com"); - emails.Add("email2@email.com"); - - var email = Email - .From(fromEmail) - .To(emails); - - email.Data.ToAddresses.Count.Should().Be(2); - } - - [Fact] - public void Can_Add_Mutlitple_Recipients_From_String_Array() - { - var emails = new string[] - { - "email1@email.com", - "email2@email.com" - }; - - var email = Email - .From(fromEmail) - .To(emails); - - email.Data.ToAddresses.Count.Should().Be(2); - } - - [Fact] - public void Can_Add_Multiple_CCRecipients_From_List() - { - var emails = new List
(); - emails.Add(new Address("email1@email.com")); - emails.Add(new Address("email2@email.com")); - - var email = Email - .From(fromEmail) - .CC(emails); - - email.Data.CcAddresses.Count.Should().Be(2); - } - - [Fact] - public void Can_Add_Multiple_BCCRecipients_From_List() - { - var emails = new List
(); - emails.Add(new Address("email1@email.com")); - emails.Add(new Address("email2@email.com")); - - var email = Email - .From(fromEmail) - .BCC(emails); - - email.Data.BccAddresses.Count.Should().Be(2); - } - - [Fact] - public void Is_Valid_With_Properties_Set() - { - var email = Email - .From(fromEmail) - .To(toEmail) - .Subject(subject) - .Body(body); - - email.Data.Body.Should().Be(body); - email.Data.Subject.Should().Be(subject); - email.Data.FromAddress.EmailAddress.Should().Be(fromEmail); - email.Data.ToAddresses[0].EmailAddress.Should().Be(toEmail); - } - - [Fact] - public void ReplyTo_Address_Is_Set() - { - var replyEmail = "reply@email.com"; - - var email = Email.From(fromEmail) - .ReplyTo(replyEmail); - - email.Data.ReplyToAddresses.First().EmailAddress.Should().Be(replyEmail); - } - - [Fact] - public void Can_Add_Mutlitple_ReplyTo_From_String_List() + new("email1@email.com"), + new("email2@email.com") + }; + + var email = Email + .From(FromEmail) + .To(emails); + + email.Data.ToAddresses.Count.Should().Be(2); + } + + [Fact] + public void Can_Add_Multiple_Recipients_From_String_List() + { + var emails = new List { - var emails = new List(); - emails.Add("email1@email.com"); - emails.Add("email2@email.com"); + "email1@email.com", + "email2@email.com" + }; - var email = Email - .From(fromEmail) - .ReplyTo(emails); + var email = Email + .From(FromEmail) + .To(emails); + + email.Data.ToAddresses.Count.Should().Be(2); + } + + [Fact] + public void Can_Add_Multiple_Recipients_From_String_Array() + { + var emails = new[] + { + "email1@email.com", + "email2@email.com" + }; - email.Data.ReplyToAddresses.Count.Should().Be(2); - } + var email = Email + .From(FromEmail) + .To(emails); - [Fact] - public void Can_Add_Mutlitple_ReplyTo_From_String_Array() + email.Data.ToAddresses.Count.Should().Be(2); + } + + [Fact] + public void Can_Add_Multiple_CCRecipients_From_List() + { + var emails = new List
+ { + new("email1@email.com"), + new("email2@email.com") + }; + + var email = Email + .From(FromEmail) + .CC(emails); + + email.Data.CcAddresses.Count.Should().Be(2); + } + + [Fact] + public void Can_Add_Multiple_BCCRecipients_From_List() + { + var emails = new List
+ { + new("email1@email.com"), + new("email2@email.com") + }; + + var email = Email + .From(FromEmail) + .BCC(emails); + + email.Data.BccAddresses.Count.Should().Be(2); + } + + [Fact] + public void Is_Valid_With_Properties_Set() + { + var email = Email + .From(FromEmail) + .To(ToEmail) + .Subject(Subject) + .Body(Body); + + email.Data.Body.Should().Be(Body); + email.Data.Subject.Should().Be(Subject); + email.Data.FromAddress.EmailAddress.Should().Be(FromEmail); + email.Data.ToAddresses[0].EmailAddress.Should().Be(ToEmail); + } + + [Fact] + public void ReplyTo_Address_Is_Set() + { + var replyEmail = "reply@email.com"; + + var email = Email.From(FromEmail) + .ReplyTo(replyEmail); + + email.Data.ReplyToAddresses.First().EmailAddress.Should().Be(replyEmail); + } + + [Fact] + public void Can_Add_Multiple_ReplyTo_From_String_List() + { + var emails = new List { - var emails = new string[] + "email1@email.com", + "email2@email.com" + }; + + var email = Email + .From(FromEmail) + .ReplyTo(emails); + + email.Data.ReplyToAddresses.Count.Should().Be(2); + } + + [Fact] + public void Can_Add_Multiple_ReplyTo_From_String_Array() + { + var emails = new[] { "email1@email.com", "email2@email.com" }; - var email = Email - .From(fromEmail) - .ReplyTo(emails); - - email.Data.ReplyToAddresses.Count.Should().Be(2); - } - -#region Refactored tests using setup through constructors. - [Fact] - public void New_To_Address_Is_Set() - { - var email = new Email(fromEmail) - .To(toEmail); - - email.Data.ToAddresses[0].EmailAddress.Should().Be(toEmail); - } - - [Fact] - public void New_From_Address_Is_Set() - { - var email = new Email(fromEmail); - - email.Data.FromAddress.EmailAddress.Should().Be(fromEmail); - } - - [Fact] - public void New_Subject_Is_Set() - { - var email = new Email(fromEmail) - .Subject(subject); - - email.Data.Subject.Should().Be(subject); - } - - [Fact] - public void New_Body_Is_Set() - { - var email = new Email(fromEmail) - .Body(body); - - email.Data.Body.Should().Be(body); - } - - [Fact] - public void New_Can_Add_Multiple_Recipients() - { - string toEmail1 = "bob@test.com"; - string toEmail2 = "ratface@test.com"; - - var email = new Email(fromEmail) - .To(toEmail1) - .To(toEmail2); - - email.Data.ToAddresses.Count.Should().Be(2); - } - - [Fact] - public void New_Can_Add_Multiple_Recipients_From_List() - { - var emails = new List
(); - emails.Add(new Address("email1@email.com")); - emails.Add(new Address("email2@email.com")); - - var email = new Email(fromEmail) - .To(emails); - - email.Data.ToAddresses.Count.Should().Be(2); - } - - [Fact] - public void New_Can_Add_Multiple_CCRecipients_From_List() - { - var emails = new List
(); - emails.Add(new Address("email1@email.com")); - emails.Add(new Address("email2@email.com")); - - var email = new Email(fromEmail) - .CC(emails); - - email.Data.CcAddresses.Count.Should().Be(2); - } - - [Fact] - public void New_Can_Add_Multiple_BCCRecipients_From_List() - { - var emails = new List
(); - emails.Add(new Address("email1@email.com")); - emails.Add(new Address("email2@email.com")); - - var email = new Email(fromEmail) - .BCC(emails); - - email.Data.BccAddresses.Count.Should().Be(2); - } - - [Fact] - public void New_Is_Valid_With_Properties_Set() - { - var email = new Email(fromEmail) - .To(toEmail) - .Subject(subject) - .Body(body); - - email.Data.Body.Should().Be(body); - email.Data.Subject.Should().Be(subject); - email.Data.FromAddress.EmailAddress.Should().Be(fromEmail); - email.Data.ToAddresses[0].EmailAddress.Should().Be(toEmail); - } - - [Fact] - public void New_ReplyTo_Address_Is_Set() - { - var replyEmail = "reply@email.com"; - - var email = new Email(fromEmail) - .ReplyTo(replyEmail); - - email.Data.ReplyToAddresses.First().EmailAddress.Should().Be(replyEmail); - } - #endregion - } -} + var email = Email + .From(FromEmail) + .ReplyTo(emails); + + email.Data.ReplyToAddresses.Count.Should().Be(2); + } + + #region Refactored tests using setup through constructors. + [Fact] + public void New_To_Address_Is_Set() + { + var email = new Email(FromEmail) + .To(ToEmail); + + email.Data.ToAddresses[0].EmailAddress.Should().Be(ToEmail); + } + + [Fact] + public void New_From_Address_Is_Set() + { + var email = new Email(FromEmail); + + email.Data.FromAddress.EmailAddress.Should().Be(FromEmail); + } + + [Fact] + public void New_Subject_Is_Set() + { + var email = new Email(FromEmail) + .Subject(Subject); + + email.Data.Subject.Should().Be(Subject); + } + + [Fact] + public void New_Body_Is_Set() + { + var email = new Email(FromEmail) + .Body(Body); + + email.Data.Body.Should().Be(Body); + } + + [Fact] + public void New_Can_Add_Multiple_Recipients() + { + var toEmail1 = "bob@test.com"; + var toEmail2 = "ratface@test.com"; + + var email = new Email(FromEmail) + .To(toEmail1) + .To(toEmail2); + + email.Data.ToAddresses.Count.Should().Be(2); + } + + [Fact] + public void New_Can_Add_Multiple_Recipients_From_List() + { + var emails = new List
+ { + new("email1@email.com"), + new("email2@email.com") + }; + + var email = new Email(FromEmail) + .To(emails); + + email.Data.ToAddresses.Count.Should().Be(2); + } + + [Fact] + public void New_Can_Add_Multiple_CCRecipients_From_List() + { + var emails = new List
+ { + new("email1@email.com"), + new("email2@email.com") + }; + + var email = new Email(FromEmail) + .CC(emails); + + email.Data.CcAddresses.Count.Should().Be(2); + } + + [Fact] + public void New_Can_Add_Multiple_BCCRecipients_From_List() + { + var emails = new List
+ { + new("email1@email.com"), + new("email2@email.com") + }; + + var email = new Email(FromEmail) + .BCC(emails); + + email.Data.BccAddresses.Count.Should().Be(2); + } + + [Fact] + public void New_Is_Valid_With_Properties_Set() + { + var email = new Email(FromEmail) + .To(ToEmail) + .Subject(Subject) + .Body(Body); + + email.Data.Body.Should().Be(Body); + email.Data.Subject.Should().Be(Subject); + email.Data.FromAddress.EmailAddress.Should().Be(FromEmail); + email.Data.ToAddresses[0].EmailAddress.Should().Be(ToEmail); + } + + [Fact] + public void New_ReplyTo_Address_Is_Set() + { + var replyEmail = "reply@email.com"; + + var email = new Email(FromEmail) + .ReplyTo(replyEmail); + + email.Data.ReplyToAddresses.First().EmailAddress.Should().Be(replyEmail); + } + #endregion +} \ No newline at end of file diff --git a/test/FluentEmail.Core.Tests/GlobalUsings.cs b/test/FluentEmail.Core.Tests/GlobalUsings.cs new file mode 100644 index 0000000..3831420 --- /dev/null +++ b/test/FluentEmail.Core.Tests/GlobalUsings.cs @@ -0,0 +1,12 @@ +// Global using directives + +global using System; +global using System.IO; +global using System.Linq; +global using System.Threading.Tasks; +global using AwesomeAssertions; +global using FluentEmail.Core.Defaults; +global using FluentEmail.Core.Interfaces; +global using FluentEmail.Core.Models; +global using Xunit; +global using Attachment = FluentEmail.Core.Models.Attachment; \ No newline at end of file diff --git a/test/FluentEmail.Core.Tests/GraphSenderTests.cs b/test/FluentEmail.Core.Tests/GraphSenderTests.cs deleted file mode 100644 index b1c2318..0000000 --- a/test/FluentEmail.Core.Tests/GraphSenderTests.cs +++ /dev/null @@ -1,101 +0,0 @@ -using FluentEmail.Core; -using FluentEmail.Core.Models; -using Xunit; -using AwesomeAssertions; -using System; -using System.IO; -using System.Threading.Tasks; - -namespace FluentEmail.Graph.Tests -{ - public class Tests - { - //TODO: For these tests to pass you will need to supply the following details from an Azure AD / Office 365 Tenant - const string appId = ""; //Add your AAD Graph App ID here - const string tenantId = ""; //Add your AAD Tenant ID here - const string graphSecret = ""; //Add your AAD Graph Client Secret here - const string senderEmail = ""; //Add a sender email address from your Office 365 tenant - const string toEmail = "fluentemail@mailinator.com"; //change this if you like - private bool saveSent = false; - - // SetUp converted to constructor - needs manual review - public void Setup() - { - if (string.IsNullOrWhiteSpace(appId)) throw new ArgumentException("Graph App ID needs to be supplied"); - if (string.IsNullOrWhiteSpace(tenantId)) throw new ArgumentException("Graph tenant ID needs to be supplied"); - if (string.IsNullOrWhiteSpace(graphSecret)) throw new ArgumentException("Graph client secret needs to be supplied"); - if (string.IsNullOrWhiteSpace(senderEmail)) throw new ArgumentException("Sender email address needs to be supplied"); - - var sender = new GraphSender(appId, tenantId, graphSecret, saveSent); - - Email.DefaultSender = sender; - } - - [Fact(Skip="Missing Graph credentials")] - public void CanSendEmail() - { - var email = Email - .From(senderEmail) - .To(toEmail) - .Subject("Test Email") - .Body("Test email from Graph sender unit test"); - - var response = email.Send(); - (response.Successful).Should().BeTrue(); - } - - [Fact(Skip="Missing Graph credentials")] - public async Task CanSendEmailAsync() - { - var email = Email - .From(senderEmail) - .To(toEmail) - .Subject("Test Async Email") - .Body("Test email from Graph sender unit test"); - - var response = await email.SendAsync(); - (response.Successful).Should().BeTrue(); - } - - [Fact(Skip="Missing Graph credentials")] - public async Task CanSendEmailWithAttachments() - { - var stream = new MemoryStream(); - var sw = new StreamWriter(stream); - sw.WriteLine("Hey this is some text in an attachment"); - sw.Flush(); - stream.Seek(0, SeekOrigin.Begin); - - var attachment = new Attachment - { - ContentType = "text/plain", - Filename = "graphtest.txt", - Data = stream - }; - - var email = Email - .From(senderEmail) - .To(toEmail) - .Subject("Test Email with Attachments") - .Body("Test email from Graph sender unit test") - .Attach(attachment); - - var response = await email.SendAsync(); - (response.Successful).Should().BeTrue(); - } - - [Fact(Skip="Missing Graph credentials")] - public async Task CanSendHighPriorityEmail() - { - var email = Email - .From(senderEmail) - .To(toEmail) - .Subject("Test High Priority Email") - .Body("Test email from Graph sender unit test") - .HighPriority(); - - var response = await email.SendAsync(); - (response.Successful).Should().BeTrue(); - } - } -} \ No newline at end of file diff --git a/test/FluentEmail.Core.Tests/MailKitSmtpSenderTests.cs b/test/FluentEmail.Core.Tests/MailKitSmtpSenderTests.cs index 8d34dc8..1b4eec6 100644 --- a/test/FluentEmail.Core.Tests/MailKitSmtpSenderTests.cs +++ b/test/FluentEmail.Core.Tests/MailKitSmtpSenderTests.cs @@ -1,194 +1,205 @@ -using System.IO; -using System.Threading.Tasks; -using FluentEmail.Core; -using FluentEmail.MailKitSmtp; -using Xunit; -using AwesomeAssertions; -using Attachment = FluentEmail.Core.Models.Attachment; - -namespace FluentEmail.MailKit.Tests -{ - // Note: XUnit runs tests in parallel by default. Use Collection attribute if sequential execution is needed. - public class MailKitSmtpSenderTests - { - // Warning: To pass, an smtp listener must be running on localhost:25. +using FluentEmail.MailKitSmtp; - const string toEmail = "bob@test.com"; - const string fromEmail = "johno@test.com"; - const string subject = "sup dawg"; - const string body = "what be the hipitity hap?"; +namespace FluentEmail.Core.Tests; + +public class MailKitSmtpSenderTests +{ + private const string ToEmail = "bob@test.com"; + private const string FromEmail = "johno@test.com"; + private const string Subject = "sup dawg"; + private const string Body = "what be the hipitity hap?"; - private readonly string tempDirectory; + private ISender GetSender(out string tempDirectory) + { + var path = Path.Combine(Path.GetTempPath(), Random.Shared.NextInt64().ToString(), "EmailTest"); - public MailKitSmtpSenderTests() + var sender = new MailKitSender(new SmtpClientOptions { - tempDirectory = Path.Combine(Path.GetTempPath(), "EmailTest"); - - var sender = new MailKitSender(new SmtpClientOptions - { - Server = "localhost", - Port = 25, - UseSsl = false, - RequiresAuthentication = false, - UsePickupDirectory = true, - MailPickupDirectory = Path.Combine(Path.GetTempPath(), "EmailTest") - }); - - Email.DefaultSender = sender; - Directory.CreateDirectory(tempDirectory); - } + Server = "localhost", + Port = 25, + UseSsl = false, + RequiresAuthentication = false, + UsePickupDirectory = true, + MailPickupDirectory = path + }); + + Directory.CreateDirectory(path); + tempDirectory = path; + return sender; + } - // Note: XUnit uses IDisposable for cleanup instead of TearDown. - public void TearDown() + private void DeleteTemp(string tempDirectory) + { + try { Directory.Delete(tempDirectory, true); } - - [Fact] - public void CanSendEmail() + // ReSharper disable once EmptyGeneralCatchClause + catch { - var email = Email - .From(fromEmail) - .To(toEmail) - .Body("

Test

", true); + } + } - var response = email.Send(); + [Fact] + public void CanSendEmail() + { + var email = Email + .From(FromEmail) + .To(ToEmail) + .Body("

Test

", true); + + email.Sender = GetSender(out var s); + + var response = email.Send(); + + var files = Directory.EnumerateFiles(s, "*.eml"); + (response.Successful).Should().BeTrue(); + (files).Should().NotBeEmpty(); + + DeleteTemp(s); + } - var files = Directory.EnumerateFiles(tempDirectory, "*.eml"); - (response.Successful).Should().BeTrue(); - (files).Should().NotBeEmpty(); - } + [Fact] + public async Task CanSendEmailWithAttachments() + { + var stream = new MemoryStream(); + var sw = new StreamWriter(stream); + await sw.WriteLineAsync("Hey this is some text in an attachment"); + await sw.FlushAsync(TestContext.Current.CancellationToken); + stream.Seek(0, SeekOrigin.Begin); - [Fact] - public async Task CanSendEmailWithAttachments() + var attachment = new Attachment { - var stream = new MemoryStream(); - var sw = new StreamWriter(stream); - sw.WriteLine("Hey this is some text in an attachment"); - sw.Flush(); - stream.Seek(0, SeekOrigin.Begin); - - var attachment = new Attachment - { - Data = stream, - ContentType = "text/plain", - Filename = "MailKitAttachment.txt" - }; - - var email = Email - .From(fromEmail) - .To(toEmail) - .Subject(subject) - .Body(body) - .Attach(attachment); - - var response = await email.SendAsync(); - - var files = Directory.EnumerateFiles(tempDirectory, "*.eml"); - (response.Successful).Should().BeTrue(); - (files).Should().NotBeEmpty(); - } + Data = stream, + ContentType = "text/plain", + Filename = "MailKitAttachment.txt" + }; + + var email = Email + .From(FromEmail) + .To(ToEmail) + .Subject(Subject) + .Body(Body) + .Attach(attachment); + + email.Sender = GetSender(out var s); + + var response = await email.SendAsync(); + + var files = Directory.EnumerateFiles(s, "*.eml"); + (response.Successful).Should().BeTrue(); + (files).Should().NotBeEmpty(); + + DeleteTemp(s); + } - [Theory] - [InlineData("logotest.png")] - public async Task CanSendEmailWithInlineImages(string contentId = null) + [Theory] + [InlineData("logotest.png")] + public async Task CanSendEmailWithInlineImages(string contentId = null) + { + await using var stream = File.OpenRead($"{Path.Combine(Directory.GetCurrentDirectory(), "logotest.png")}"); + var attachment = new Attachment { - using (var stream = File.OpenRead($"{Path.Combine(Directory.GetCurrentDirectory(), "logotest.png")}")) - { - var attachment = new Attachment - { - IsInline = true, - Data = stream, - ContentType = "image/png", - Filename = "logotest.png", - ContentId = contentId - }; - - var email = Email - .From(fromEmail) - .To(toEmail) - .Subject(subject) - .Body("Inline image here: " + - "

You should see an image without an attachment, or without a download prompt, depending on the email client.

", true) - .Attach(attachment); - - var response = await email.SendAsync(); - - var files = Directory.EnumerateFiles(tempDirectory, "*.eml"); - (response.Successful).Should().BeTrue(); - (files).Should().NotBeEmpty(); - } - } + IsInline = true, + Data = stream, + ContentType = "image/png", + Filename = "logotest.png", + ContentId = contentId + }; + + var email = Email + .From(FromEmail) + .To(ToEmail) + .Subject(Subject) + .Body("Inline image here: " + + "

You should see an image without an attachment, or without a download prompt, depending on the email client.

", true) + .Attach(attachment); + + email.Sender = GetSender(out var s); + var response = await email.SendAsync(); + + var files = Directory.EnumerateFiles(s, "*.eml"); + (response.Successful).Should().BeTrue(); + (files).Should().NotBeEmpty(); + DeleteTemp(s); + } - [Fact] - public async Task CanSendEmailWithInlineImagesAndAttachmentTogether() + [Fact] + public async Task CanSendEmailWithInlineImagesAndAttachmentTogether() + { + var attachmentStream = new MemoryStream(); + var sw = new StreamWriter(attachmentStream); + await sw.WriteLineAsync("Hey this is some text in an attachment"); + await sw.FlushAsync(TestContext.Current.CancellationToken); + attachmentStream.Seek(0, SeekOrigin.Begin); + + var attachment = new Attachment { - var attachmentStream = new MemoryStream(); - var sw = new StreamWriter(attachmentStream); - sw.WriteLine("Hey this is some text in an attachment"); - sw.Flush(); - attachmentStream.Seek(0, SeekOrigin.Begin); - - var attachment = new Attachment - { - Data = attachmentStream, - ContentType = "text/plain", - Filename = "MailKitAttachment.txt", - }; - - using var inlineStream = File.OpenRead($"{Path.Combine(Directory.GetCurrentDirectory(), "logotest.png")}"); - - var attachmentInline = new Attachment - { - IsInline = true, - Data = inlineStream, - ContentType = "image/png", - Filename = "logotest.png", - }; - - var email = Email - .From(fromEmail) - .To(toEmail) - .Subject(subject) - .Body("Inline image here: " + - "

You should see an image inline without a picture attachment.

" + - "

A single .txt file should also be attached.

", true) - .Attach(attachment) - .Attach(attachmentInline); - - var response = await email.SendAsync(); - - var files = Directory.EnumerateFiles(tempDirectory, "*.eml"); - (response.Successful).Should().BeTrue(); - (files).Should().NotBeEmpty(); - } + Data = attachmentStream, + ContentType = "text/plain", + Filename = "MailKitAttachment.txt", + }; + + await using var inlineStream = File.OpenRead($"{Path.Combine(Directory.GetCurrentDirectory(), "logotest.png")}"); - [Fact] - public async Task CanSendAsyncHtmlAndPlaintextTogether() + var attachmentInline = new Attachment { - var email = Email - .From(fromEmail) - .To(toEmail) - .Body("

Test

some body text

", true) - .PlaintextAlternativeBody("Test - Some body text"); + IsInline = true, + Data = inlineStream, + ContentType = "image/png", + Filename = "logotest.png", + }; + + var email = Email + .From(FromEmail) + .To(ToEmail) + .Subject(Subject) + .Body("Inline image here: " + + "

You should see an image inline without a picture attachment.

" + + "

A single .txt file should also be attached.

", true) + .Attach(attachment) + .Attach(attachmentInline); + + email.Sender = GetSender(out var s); + + var response = await email.SendAsync(); + + var files = Directory.EnumerateFiles(s, "*.eml"); + (response.Successful).Should().BeTrue(); + (files).Should().NotBeEmpty(); + + DeleteTemp(s); + } - var response = await email.SendAsync(); + [Fact] + public async Task CanSendAsyncHtmlAndPlaintextTogether() + { + var email = Email + .From(FromEmail) + .To(ToEmail) + .Body("

Test

some body text

", true) + .PlaintextAlternativeBody("Test - Some body text"); - (response.Successful).Should().BeTrue(); - } + email.Sender = GetSender(out var s); + var response = await email.SendAsync(); + DeleteTemp(s); - [Fact] - public void CanSendHtmlAndPlaintextTogether() - { - var email = Email - .From(fromEmail) - .To(toEmail) - .Body("

Test

some body text

", true) - .PlaintextAlternativeBody("Test - Some body text"); + (response.Successful).Should().BeTrue(); + } + + [Fact] + public void CanSendHtmlAndPlaintextTogether() + { + var email = Email + .From(FromEmail) + .To(ToEmail) + .Body("

Test

some body text

", true) + .PlaintextAlternativeBody("Test - Some body text"); - var response = email.Send(); + email.Sender = GetSender(out var s); + var response = email.Send(); + DeleteTemp(s); - (response.Successful).Should().BeTrue(); - } + (response.Successful).Should().BeTrue(); } -} +} \ No newline at end of file diff --git a/test/FluentEmail.Core.Tests/MailgunSenderTests.cs b/test/FluentEmail.Core.Tests/MailgunSenderTests.cs deleted file mode 100644 index b529348..0000000 --- a/test/FluentEmail.Core.Tests/MailgunSenderTests.cs +++ /dev/null @@ -1,156 +0,0 @@ -using System.IO; -using System.Threading.Tasks; -using FluentEmail.Core; -using FluentEmail.Core.Models; -using Xunit; -using AwesomeAssertions; -using Newtonsoft.Json; - -namespace FluentEmail.Mailgun.Tests -{ - public class MailgunSenderTests - { - const string toEmail = "bentest1@mailinator.com"; - const string fromEmail = "ben@test.com"; - const string subject = "Attachment Tests"; - const string body = "This email is testing the attachment functionality of MailGun."; - - public MailgunSenderTests() - { - var sender = new MailgunSender("", ""); - Email.DefaultSender = sender; - } - - [Fact(Skip="Missing credentials")] - public async Task CanSendEmail() - { - var email = Email - .From(fromEmail) - .To(toEmail) - .Subject(subject) - .Body(body); - - var response = await email.SendAsync(); - - (response.Successful).Should().BeTrue(); - } - - [Fact(Skip="Missing credentials")] - public async Task GetMessageIdInResponse() - { - var email = Email - .From(fromEmail) - .To(toEmail) - .Subject(subject) - .Body(body); - - var response = await email.SendAsync(); - - (response.Successful).Should().BeTrue(); - (response.MessageId).Should().NotBeEmpty(); - } - - [Fact(Skip="Missing credentials")] - public async Task CanSendEmailWithTag() - { - var email = Email - .From(fromEmail) - .To(toEmail) - .Subject(subject) - .Body(body) - .Tag("test"); - - var response = await email.SendAsync(); - - (response.Successful).Should().BeTrue(); - } - - [Fact(Skip="Missing credentials")] - public async Task CanSendEmailWithVariables() - { - var email = Email - .From(fromEmail) - .To(toEmail) - .Subject(subject) - .Body(body) - .Header("X-Mailgun-Variables", JsonConvert.SerializeObject(new Variable { Var1 = "Test"})); - - var response = await email.SendAsync(); - - (response.Successful).Should().BeTrue(); - } - - [Fact(Skip="Missing credentials")] - public async Task CanSendEmailWithAttachments() - { - var stream = new MemoryStream(); - var sw = new StreamWriter(stream); - sw.WriteLine("Hey this is some text in an attachment"); - sw.Flush(); - stream.Seek(0, SeekOrigin.Begin); - - var attachment = new Attachment - { - Data = stream, - ContentType = "text/plain", - Filename = "mailgunTest.txt" - }; - - var email = Email - .From(fromEmail) - .To(toEmail) - .Subject(subject) - .Body(body) - .Attach(attachment); - - var response = await email.SendAsync(); - - (response.Successful).Should().BeTrue(); - } - - [Fact(Skip="Missing credentials")] - public async Task CanSendEmailWithInlineImages() - { - using (var stream = File.OpenRead($"{Path.Combine(Directory.GetCurrentDirectory(), "logotest.png")}")) - { - var attachment = new Attachment - { - IsInline = true, - Data = stream, - ContentType = "image/png", - Filename = "logotest.png" - }; - - var email = Email - .From(fromEmail) - .To(toEmail) - .Subject(subject) - .Body("Inline image here: " + - "

You should see an image without an attachment, or without a download prompt, depending on the email client.

", true) - .Attach(attachment); - - var response = await email.SendAsync(); - - (response.Successful).Should().BeTrue(); - } - } - - // [Fact] - // public async Task CanSendEmailWithTemplate() - // { - // var email = Email - // .From(fromEmail) - // .To(toEmail) - // .Subject(subject); - // - // var response = await email.SendWithTemplateAsync("test-template", new { var1 = "Test" }); - // - // (response.Successful).Should().BeTrue(); - // } - - class Variable - { - public string Var1 { get; set; } - } - } -} \ No newline at end of file diff --git a/test/FluentEmail.Core.Tests/MailtrapSenderTests.cs b/test/FluentEmail.Core.Tests/MailtrapSenderTests.cs deleted file mode 100644 index bd4593e..0000000 --- a/test/FluentEmail.Core.Tests/MailtrapSenderTests.cs +++ /dev/null @@ -1,118 +0,0 @@ -using System.IO; -using System.Threading.Tasks; -using FluentEmail.Core; -using FluentEmail.Core.Models; -using Xunit; -using AwesomeAssertions; - -namespace FluentEmail.Mailtrap.Tests -{ - public class MailtrapSenderTests - { - const string toEmail = "neo.js.cn@gmail.com"; - const string fromEmail = "mailtrap@blazorserver.com"; - const string subject = "Mailtrap Email Test"; - const string body = "This email is testing the functionality of mailtrap."; - const string username = ""; // Mailtrap SMTP inbox username - const string password = ""; // Mailtrap SMTP inbox password - const string templateid = ""; - - public MailtrapSenderTests() - { - var sender = new MailtrapSender(username, password, "send.api.mailtrap.io", 587); - Email.DefaultSender = sender; - } - - [Fact(Skip="Missing credentials")] - public void CanSendEmail() - { - var email = Email - .From(fromEmail) - .To(toEmail) - .Subject(subject) - .Body(body); - - var response = email.Send(); - - (response.Successful).Should().BeTrue(); - } - - - [Fact(Skip="Missing credentials")] - public async Task CanSendEmailAsync() - { - var email = Email - .From(fromEmail) - .To(toEmail) - .Subject(subject) - .Body(body); - - var response = await email.SendAsync(); - - (response.Successful).Should().BeTrue(); - } - - [Fact(Skip="Missing credentials")] - public async Task CanSendEmailWithAttachments() - { - var stream = new MemoryStream(); - var sw = new StreamWriter(stream); - sw.WriteLine("Hey this is some text in an attachment"); - sw.Flush(); - stream.Seek(0, SeekOrigin.Begin); - - var attachment = new Attachment - { - Data = stream, - ContentType = "text/plain", - Filename = "mailtrapTest.txt" - }; - - var email = Email - .From(fromEmail) - .To(toEmail) - .Subject(subject) - .Body(body) - .Attach(attachment); - - var response = await email.SendAsync(); - - (response.Successful).Should().BeTrue(); - } - - [Fact(Skip="Missing credentials")] - public async Task CanSendEmailWithInlineImages() - { - using (var stream = File.OpenRead($"{Path.Combine(Directory.GetCurrentDirectory(), "logotest.png")}")) - { - var attachment = new Attachment - { - IsInline = true, - Data = stream, - ContentType = "image/png", - Filename = "logotest.png" - }; - - var email = Email - .From(fromEmail) - .To(toEmail) - .Subject(subject) - .Body("Inline image here: " + - "

You should see an image without an attachment, or without a download prompt, depending on the email client.

", true) - .Attach(attachment); - - var response = await email.SendAsync(); - - (response.Successful).Should().BeTrue(); - } - } - - [Fact(Skip="Missing credentials")] - public async Task CanSendEmailWithTemplate() - { - var email = Email.From(fromEmail).To(toEmail); - var response = await email.SendWithTemplateAsync(templateid, new { var1 = "Test", var2 = "VVVVVVVVVVVVV" }); - (response.Successful).Should().BeTrue(); - } - } -} diff --git a/test/FluentEmail.Core.Tests/NonParallelCollection.cs b/test/FluentEmail.Core.Tests/NonParallelCollection.cs deleted file mode 100644 index aac3d63..0000000 --- a/test/FluentEmail.Core.Tests/NonParallelCollection.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Xunit; - -namespace FluentEmail.Core.Tests -{ - [CollectionDefinition("NonParallel", DisableParallelization = true)] - public class NonParallelCollection - { - } -} diff --git a/test/FluentEmail.Core.Tests/PostmarkSenderTests.cs b/test/FluentEmail.Core.Tests/PostmarkSenderTests.cs deleted file mode 100644 index 1fe38d7..0000000 --- a/test/FluentEmail.Core.Tests/PostmarkSenderTests.cs +++ /dev/null @@ -1,294 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using AwesomeAssertions; -using FluentEmail.Core; -using Xunit; -using AwesomeAssertions; - -namespace FluentEmail.Postmark.Tests -{ - // Skipped: missing Postmark API key - tests in this class will be skipped - public class WithTestApiToken - { - - const string apiKey = "postmark-api-key"; // TODO: Put your API key here - const string toEmail = "test@blackhole.postmarkapp.com"; - const string toEmailHash = "test+test@blackhole.postmarkapp.com"; - const string toEmailHash2 = "test+second@blackhole.postmarkapp.com"; - const string toName = "Test Name"; - const string fromEmail = "insert-sender-signature-here"; - const string fromName = "from name"; - const string fromEmailHash = "insert-sender-signature-here"; - - [Fact] - public void SimpleMailFromCodeSync() - { - Email.DefaultSender = new PostmarkSender(apiKey); - - var response = Email - .From(fromEmail, fromName) - .To(toEmail) - .Subject("hows it going bob") - .Body("yo dawg, sup?") - .Send(); - - response.Successful.Should().BeTrue(); - } - - [Fact] - public async Task SimpleMailFromCode() - { - Email.DefaultSender = new PostmarkSender(apiKey); - - var response = await Email - .From(fromEmail) - .To(toEmail) - .Subject("hows it going bob") - .Body("yo dawg, sup?") - .SendAsync() - .ConfigureAwait(false); - - response.Successful.Should().BeTrue(); - response.MessageId.Should().NotBeNullOrEmpty(); - response.ErrorMessages.Should().BeEmpty(); - } - - [Fact] - public async Task SimpleMailFromCodeWithAddressesWithPlus() - { - Email.DefaultSender = new PostmarkSender(apiKey); - - var response = await Email - .From(fromEmailHash) - .To(toEmailHash) - .ReplyTo(toEmailHash2) - .Subject("hows it going bob") - .Body("yo dawg, sup?") - .SendAsync() - .ConfigureAwait(false); - - response.Successful.Should().BeTrue(); - response.MessageId.Should().NotBeNullOrEmpty(); - response.ErrorMessages.Should().BeEmpty(); - } - - [Fact] - public async Task SimpleMailReplyTo() - { - Email.DefaultSender = new PostmarkSender(apiKey); - - var response = await Email - .From(fromEmail) - .To(toEmail) - .ReplyTo(fromEmail) - .Subject("hows it going bob") - .Body("yo dawg, sup?") - .SendAsync() - .ConfigureAwait(false); - - response.Successful.Should().BeTrue(); - response.MessageId.Should().NotBeNullOrEmpty(); - response.ErrorMessages.Should().BeEmpty(); - } - - [Fact] - public async Task SimpleMailWithNameFromCode() - { - Email.DefaultSender = new PostmarkSender(apiKey); - - var response = await Email - .From(fromEmail, fromName) - .To(toEmail) - .Subject("hows it going bob") - .Body("yo dawg, sup?") - .SendAsync() - .ConfigureAwait(false); - - response.Successful.Should().BeTrue(); - response.MessageId.Should().NotBeNullOrEmpty(); - response.ErrorMessages.Should().BeEmpty(); - } - - [Fact] - public async Task SimpleHtmlMailFromCode() - { - Email.DefaultSender = new PostmarkSender(apiKey); - - var response = await Email - .From(fromEmail, fromName) - .To(toEmail) - .Subject("hows it going bob") - .Body("

Test

", true) - .SendAsync() - .ConfigureAwait(false); - - response.Successful.Should().BeTrue(); - } - - [Fact] - public async Task SimpleMailWithAttachmentFromCode() - { - Email.DefaultSender = new PostmarkSender(apiKey); - - var response = await Email - .From(fromEmail, fromName) - .To(toEmail) - .Subject("hows it going bob") - .Body("yo dawg, sup?") - .Attach(new Core.Models.Attachment() - { - Filename = "test.txt", - Data = new System.IO.MemoryStream(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7 }), - ContentType = "application/octet-stream" - }) - .SendAsync() - .ConfigureAwait(false); - - response.Successful.Should().BeTrue(); - response.MessageId.Should().NotBeNullOrEmpty(); - response.ErrorMessages.Should().BeEmpty(); - } - - [Fact] - public async Task SimpleHtmlMailWithAlternFromCode() - { - Email.DefaultSender = new PostmarkSender(apiKey); - - var response = await Email - .From(fromEmail, fromName) - .To(toEmail) - .Subject("hows it going bob") - .Body("

Test

", true) - .PlaintextAlternativeBody("Test") - .SendAsync() - .ConfigureAwait(false); - - response.Successful.Should().BeTrue(); - } - - [Fact] - public async Task SimpleMailFromCodeWithOpts() - { - var opts = new PostmarkSenderOptions(apiKey); - opts.TrackOpens = true; - opts.TrackLinks = PostmarkDotNet.LinkTrackingOptions.HtmlAndText; - opts.Tag = "unittest"; - opts.Metadata = new Dictionary() { { "key", "example" } }; - Email.DefaultSender = new PostmarkSender(opts); - - var response = await Email - .From(fromEmail, fromName) - .To(toEmail) - .Subject("hows it going bob") - .Body("yo dawg, sup?") - .SendAsync() - .ConfigureAwait(false); - - response.Successful.Should().BeTrue(); - } - - [Fact] - public async Task SimpleMailFromCodeWithLowPrio() - { - Email.DefaultSender = new PostmarkSender(apiKey); - - var response = await Email - .From(fromEmail, fromName) - .To(toEmail) - .Subject("hows it going bob") - .Body("yo dawg, sup?") - .LowPriority() - .SendAsync() - .ConfigureAwait(false); - - response.Successful.Should().BeTrue(); - } - - [Fact] - public async Task SimpleMailFromCodeWithHighPrio() - { - Email.DefaultSender = new PostmarkSender(apiKey); - - var response = await Email - .From(fromEmail, fromName) - .To(toEmail) - .Subject("hows it going bob") - .Body("yo dawg, sup?") - .HighPriority() - .SendAsync() - .ConfigureAwait(false); - - response.Successful.Should().BeTrue(); - } - - [Fact] - public async Task SimpleMailFromCodeWithHeaders() - { - Email.DefaultSender = new PostmarkSender(apiKey); - - var response = await Email - .From(fromEmail, fromName) - .To(toEmail) - .Subject("hows it going bob") - .Body("yo dawg, sup?") - .Header("X-Random-Useless-Header", "SomeValue") - .Header("X-Another-Random-Useless-Header", "AnotherValue") - .SendAsync() - .ConfigureAwait(false); - - response.Successful.Should().BeTrue(); - } - - [Fact] - public void SenderNullServerToken() - { - Func fn = () => new PostmarkSender((string)null!); - fn.Should().Throw(); - } - - [Fact] - public void OptionsNullServerToken() - { - Func fn = () => new PostmarkSenderOptions(null!); - fn.Should().Throw(); - } - - [Fact] - public void NullOptions() - { - Func fn = () => new PostmarkSender((PostmarkSenderOptions)null!); - fn.Should().Throw(); - } - - [Fact] - public void SendNull() - { - var sender = new PostmarkSender(apiKey); - Func fn = async () => await sender.SendAsync(null!).ConfigureAwait(false); - fn.Should().ThrowAsync(); - } - - [Fact] - public async Task TooManyRecipients() - { - Email.DefaultSender = new PostmarkSender(apiKey); - - var mail = Email - .From(fromEmail, fromName) - .Subject("hows it going bob") - .Body("yo dawg, sup?"); - - var recipAdrs = new List(); - for (var i = 0; i < 60; i++) - recipAdrs.Add($"test{i}@blackhole.postmarkapp.com"); - - var recips = recipAdrs.Select(s => new FluentEmail.Core.Models.Address(s)).ToList(); - mail.To(recips); - - Func act = async () => { await mail.SendAsync().ConfigureAwait(false); }; - await act.Should().ThrowAsync().ConfigureAwait(false); - } - } -} diff --git a/test/FluentEmail.Core.Tests/ReplaceRendererTest.cs b/test/FluentEmail.Core.Tests/ReplaceRendererTest.cs index 61367d5..14d1885 100644 --- a/test/FluentEmail.Core.Tests/ReplaceRendererTest.cs +++ b/test/FluentEmail.Core.Tests/ReplaceRendererTest.cs @@ -1,25 +1,18 @@ -using FluentEmail.Core.Defaults; -using FluentEmail.Core.Interfaces; -using FluentEmail.Core.Models; -using Xunit; -using AwesomeAssertions; +namespace FluentEmail.Core.Tests; -namespace FluentEmail.Core.Tests +public class ReplaceRendererTest { - public class ReplaceRendererTest + [Fact] + public void ModelPropertyValueIsNull_Test() { - [Fact] - public void ModelPropertyValueIsNull_Test() - { - ITemplateRenderer templateRenderer = new ReplaceRenderer(); + ITemplateRenderer templateRenderer = new ReplaceRenderer(); - var address = new Address("james@test.com", "james"); - address.Name.Should().Be("james"); - var template = "this is name: ##Name##"; - templateRenderer.Parse(template, address).Should().Be("this is name: james"); + var address = new Address("james@test.com", "james"); + address.Name.Should().Be("james"); + var template = "this is name: ##Name##"; + templateRenderer.Parse(template, address).Should().Be("this is name: james"); - address.Name = null; - templateRenderer.Parse(template, address).Should().Be("this is name: "); - } + address.Name = null; + templateRenderer.Parse(template, address).Should().Be("this is name: "); } } \ No newline at end of file diff --git a/test/FluentEmail.Core.Tests/SendGridSenderTests.cs b/test/FluentEmail.Core.Tests/SendGridSenderTests.cs deleted file mode 100644 index 18fe947..0000000 --- a/test/FluentEmail.Core.Tests/SendGridSenderTests.cs +++ /dev/null @@ -1,201 +0,0 @@ -using FluentEmail.Core; -using Xunit; -using AwesomeAssertions; -using System; -using System.IO; -using System.Threading.Tasks; -using Attachment = FluentEmail.Core.Models.Attachment; - -namespace FluentEmail.SendGrid.Tests -{ - public class SendGridSenderTests - { - const string apiKey = "missing-credentials"; // TODO: Put your API key here - - const string toEmail = "fluentEmail@mailinator.com"; - const string toName = "FluentEmail Mailinator"; - const string fromEmail = "test@fluentmail.com"; - const string fromName = "SendGridSender Test"; - - public SendGridSenderTests() - { - if (string.IsNullOrWhiteSpace(apiKey)) throw new ArgumentException("SendGrid Api Key needs to be supplied"); - - var sender = new SendGridSender(apiKey, true); - Email.DefaultSender = sender; - } - - [Fact(Skip="No sendgrid credentials")] - public async Task CanSendEmail() - { - const string subject = "SendMail Test"; - const string body = "This email is testing send mail functionality of SendGrid Sender."; - - var email = Email - .From(fromEmail, fromName) - .To(toEmail, toName) - .Subject(subject) - .Body(body); - - var response = await email.SendAsync(); - - (response.Successful).Should().BeTrue(); - } - - [Fact(Skip="No sendgrid credentials")] - public async Task CanSendTemplateEmail() - { - const string subject = "SendMail Test"; - const string templateId = "123456-insert-your-own-id-here"; - object templateData = new - { - Name = toName, - ArbitraryValue = "The quick brown fox jumps over the lazy dog." - }; - - var email = Email - .From(fromEmail, fromName) - .To(toEmail, toName) - .Subject(subject); - - var response = await email.SendWithTemplateAsync(templateId, templateData); - - (response.Successful).Should().BeTrue(); - } - - [Fact(Skip="No sendgrid credentials")] - public async Task CanSendEmailWithReplyTo() - { - const string subject = "SendMail Test"; - const string body = "This email is testing send mail with ReplyTo functionality of SendGrid Sender."; - - var email = Email - .From(fromEmail, fromName) - .To(toEmail, toName) - .ReplyTo(toEmail, toName) - .Subject(subject) - .Body(body); - - var response = await email.SendAsync(); - - (response.Successful).Should().BeTrue(); - } - - [Fact(Skip="No sendgrid credentials")] - public async Task CanSendEmailWithCategory() - { - const string subject = "SendMail Test"; - const string body = "This email is testing send mail with Categories functionality of SendGrid Sender."; - - var email = Email - .From(fromEmail, fromName) - .To(toEmail, toName) - .ReplyTo(toEmail, toName) - .Subject(subject) - .Tag("TestCategory") - .Body(body); - - var response = await email.SendAsync(); - - (response.Successful).Should().BeTrue(); - } - - [Fact(Skip="No sendgrid credentials")] - public async Task CanSendEmailWithAttachments() - { - const string subject = "SendMail With Attachments Test"; - const string body = "This email is testing the attachment functionality of SendGrid Sender."; - - using (var stream = File.OpenRead($"{Directory.GetCurrentDirectory()}/test-binary.xlsx")) - { - var attachment = new Attachment - { - Data = stream, - ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", - Filename = "test-binary.xlsx" - }; - - var email = Email - .From(fromEmail, fromName) - .To(toEmail, toName) - .Subject(subject) - .Body(body) - .Attach(attachment); - - - var response = await email.SendAsync(); - - (response.Successful).Should().BeTrue(); - } - } - - [Fact(Skip="No sendgrid credentials")] - public async Task CanSendHighPriorityEmail() - { - const string subject = "SendMail Test"; - const string body = "This email is testing send mail functionality of SendGrid Sender."; - - var email = Email - .From(fromEmail, fromName) - .To(toEmail, toName) - .Subject(subject) - .Body(body) - .HighPriority(); - - var response = await email.SendAsync(); - - (response.Successful).Should().BeTrue(); - } - - [Fact(Skip="No sendgrid credentials")] - public async Task CanSendLowPriorityEmail() - { - const string subject = "SendMail Test"; - const string body = "This email is testing send mail functionality of SendGrid Sender."; - - var email = Email - .From(fromEmail, fromName) - .To(toEmail, toName) - .Subject(subject) - .Body(body) - .LowPriority(); - - var response = await email.SendAsync(); - - (response.Successful).Should().BeTrue(); - } - - [Fact(Skip="No sendgrid credentials")] - public async Task CanSendEmailWithInlineAttachments() - { - // Arrange - const string subject = "SendMail With Inline Attachments Test"; - const string body = "This email is testing the inline attachment functionality of SendGrid Sender."; - - using (var stream = File.OpenRead($"{Directory.GetCurrentDirectory()}/logotest.png")) - { - var attachment = new Attachment - { - Data = stream, - ContentType = "image/png", - Filename = "logotest.png", - IsInline = true, - ContentId = "logotest_id" - }; - - var email = Email - .From(fromEmail, fromName) - .To(toEmail, toName) - .Subject(subject) - .Body(body) - .Attach(attachment); - - // Act - var response = await email.SendAsync(); - - // Assert - (response.Successful).Should().BeTrue(); - } - } - } -} \ No newline at end of file diff --git a/test/FluentEmail.Core.Tests/SmtpSenderTests.cs b/test/FluentEmail.Core.Tests/SmtpSenderTests.cs index 41a5b99..e3a441f 100644 --- a/test/FluentEmail.Core.Tests/SmtpSenderTests.cs +++ b/test/FluentEmail.Core.Tests/SmtpSenderTests.cs @@ -1,127 +1,145 @@ -using System.IO; -using System.Net.Mail; +using System.Net.Mail; using System.Threading; -using System.Threading.Tasks; -using FluentEmail.Core; -using Xunit; -using AwesomeAssertions; -using Attachment = FluentEmail.Core.Models.Attachment; +using FluentEmail.Smtp; -namespace FluentEmail.Smtp.Tests +namespace FluentEmail.Core.Tests; + +public class SmtpSenderTests { - // Note: XUnit runs tests in parallel by default. Use Collection attribute if sequential execution is needed. - public class SmtpSenderTests + private const string ToEmail = "bob@test.com"; + private const string FromEmail = "johno@test.com"; + private const string Subject = "sup dawg"; + private const string Body = "what be the hipitity hap?"; + + private static IFluentEmail TestEmail => Email + .From(FromEmail) + .To(ToEmail) + .Subject(Subject) + .Body(Body); + + private ISender GetSender(out string tempDirectory) { - // Warning: To pass, an smtp listener must be running on localhost:25. - - const string toEmail = "bob@test.com"; - const string fromEmail = "johno@test.com"; - const string subject = "sup dawg"; - const string body = "what be the hipitity hap?"; - - private static IFluentEmail TestEmail => Email - .From(fromEmail) - .To(toEmail) - .Subject(subject) - .Body(body); + var path = Path.Combine(Path.GetTempPath(), Random.Shared.NextInt64().ToString(), "EmailTest"); - private readonly string tempDirectory; - - public SmtpSenderTests() + var sender = new SmtpSender(() => new SmtpClient("localhost") { - tempDirectory = Path.Combine(Path.GetTempPath(), "EmailTest"); - - var sender = new SmtpSender(() => new SmtpClient("localhost") - { - EnableSsl = false, - DeliveryMethod = SmtpDeliveryMethod.SpecifiedPickupDirectory, - PickupDirectoryLocation = tempDirectory - }); - - Email.DefaultSender = sender; - Directory.CreateDirectory(tempDirectory); - } + EnableSsl = false, + DeliveryMethod = SmtpDeliveryMethod.SpecifiedPickupDirectory, + PickupDirectoryLocation = path + }); + + Directory.CreateDirectory(path); + tempDirectory = path; + return sender; + } - // Note: XUnit uses IDisposable for cleanup instead of TearDown. - public void TearDown() + private void DeleteTemp(string tempDirectory) + { + try { Directory.Delete(tempDirectory, true); } - - [Fact] - public void CanSendEmail() + // ReSharper disable once EmptyGeneralCatchClause + catch { - var email = TestEmail - .Body("

Test

", true); + } + } - var response = email.Send(); - var files = Directory.EnumerateFiles(tempDirectory, "*.eml"); - (response.Successful).Should().BeTrue(); - (files).Should().NotBeEmpty(); - } + [Fact] + public void CanSendEmail() + { + var email = TestEmail + .Body("

Test

", true); - [Fact] - public async Task CanSendEmailWithAttachments() - { - var stream = new MemoryStream(); - var sw = new StreamWriter(stream); - sw.WriteLine("Hey this is some text in an attachment"); - sw.Flush(); - stream.Seek(0, SeekOrigin.Begin); - - var attachment = new Attachment - { - Data = stream, - ContentType = "text/plain", - Filename = "mailgunTest.txt" - }; - - var email = TestEmail - .Attach(attachment); - - var response = await email.SendAsync(); - - (response.Successful).Should().BeTrue(); - var files = Directory.EnumerateFiles(tempDirectory, "*.eml"); - (files).Should().NotBeEmpty(); - } + email.Sender = GetSender(out var s); - [Fact] - public async Task CanSendAsyncHtmlAndPlaintextTogether() - { - var email = TestEmail - .Body("

Test

some body text

", true) - .PlaintextAlternativeBody("Test - Some body text"); + var response = email.Send(); - var response = await email.SendAsync(); + var files = Directory.EnumerateFiles(s, "*.eml"); + (response.Successful).Should().BeTrue(); + (files).Should().NotBeEmpty(); + DeleteTemp(s); - (response.Successful).Should().BeTrue(); - } + } - [Fact] - public void CanSendHtmlAndPlaintextTogether() + [Fact] + public async Task CanSendEmailWithAttachments() + { + var stream = new MemoryStream(); + var sw = new StreamWriter(stream); + await sw.WriteLineAsync("Hey this is some text in an attachment"); + await sw.FlushAsync(TestContext.Current.CancellationToken); + stream.Seek(0, SeekOrigin.Begin); + + var attachment = new Attachment { - var email = TestEmail - .Body("

Test

some body text

", true) - .PlaintextAlternativeBody("Test - Some body text"); + Data = stream, + ContentType = "text/plain", + Filename = "mailgunTest.txt" + }; - var response = email.Send(); + var email = TestEmail + .Attach(attachment); - (response.Successful).Should().BeTrue(); - } + email.Sender = GetSender(out var s); - [Fact] - public void CancelSendIfCancelationRequested() - { - var email = TestEmail; + var response = await email.SendAsync(); - var tokenSource = new CancellationTokenSource(); - tokenSource.Cancel(); + (response.Successful).Should().BeTrue(); + var files = Directory.EnumerateFiles(s, "*.eml"); + (files).Should().NotBeEmpty(); - var response = email.Send(tokenSource.Token); + DeleteTemp(s); - (response.Successful).Should().BeFalse(); - } + } + + [Fact] + public async Task CanSendAsyncHtmlAndPlaintextTogether() + { + var email = TestEmail + .Body("

Test

some body text

", true) + .PlaintextAlternativeBody("Test - Some body text"); + + email.Sender = GetSender(out var s); + + var response = await email.SendAsync(); + + DeleteTemp(s); + + (response.Successful).Should().BeTrue(); + } + + [Fact] + public void CanSendHtmlAndPlaintextTogether() + { + var email = TestEmail + .Body("

Test

some body text

", true) + .PlaintextAlternativeBody("Test - Some body text"); + + email.Sender = GetSender(out var s); + + var response = email.Send(); + + DeleteTemp(s); + + (response.Successful).Should().BeTrue(); + } + + [Fact] + public void CancelSendIfCancellationRequested() + { + var email = TestEmail; + + var tokenSource = new CancellationTokenSource(); + tokenSource.Cancel(); + + email.Sender = GetSender(out var s); + + var response = email.Send(tokenSource.Token); + + DeleteTemp(s); + + (response.Successful).Should().BeFalse(); } } diff --git a/test/FluentEmail.Core.Tests/TemplateEmailTests.cs b/test/FluentEmail.Core.Tests/TemplateEmailTests.cs index ac58567..49811d7 100644 --- a/test/FluentEmail.Core.Tests/TemplateEmailTests.cs +++ b/test/FluentEmail.Core.Tests/TemplateEmailTests.cs @@ -1,225 +1,218 @@ using System.Globalization; -using System.IO; using System.Reflection; -using System.Threading.Tasks; -using FluentEmail.Core.Defaults; -using FluentEmail.Core.Interfaces; -using Xunit; -using AwesomeAssertions; -namespace FluentEmail.Core.Tests +namespace FluentEmail.Core.Tests; + +public class TemplateEmailTests { - public class TemplateEmailTests - { - private Assembly ThisAssembly() => this.GetType().GetTypeInfo().Assembly; - const string toEmail = "bob@test.com"; - const string fromEmail = "johno@test.com"; - const string subject = "sup dawg"; - - [Fact] - public void Anonymous_Model_Template_From_File_Matches() - { - var email = Email - .From(fromEmail) - .To(toEmail) - .Subject(subject) - .UsingTemplateFromFile($"{Path.Combine(Directory.GetCurrentDirectory(), "test.txt")}", new { Test = "FLUENTEMAIL" }); - - email.Data.Body.Should().Be("yo email FLUENTEMAIL"); - } - - [Fact] - public void Using_Template_From_Not_Existing_Culture_File_Using_Default_Template() - { - var culture = new CultureInfo("fr-FR"); - var email = Email - .From(fromEmail) - .To(toEmail) - .Subject(subject) - .UsingCultureTemplateFromFile($"{Path.Combine(Directory.GetCurrentDirectory(), "test.txt")}", new { Test = "FLUENTEMAIL", culture }, culture); - - email.Data.Body.Should().Be("yo email FLUENTEMAIL"); - } - - [Fact] - public void Using_Template_From_Culture_File() - { - var culture = new CultureInfo("he-IL"); - var email = Email - .From(fromEmail) - .To(toEmail) - .Subject(subject) - .UsingCultureTemplateFromFile($"{Path.Combine(Directory.GetCurrentDirectory(), "test.txt")}", new { Test = "FLUENTEMAIL" }, culture); - - email.Data.Body.Should().Be("hebrew email FLUENTEMAIL"); - } - - [Fact] - public void Using_Template_From_Current_Culture_File() - { - var culture = new CultureInfo("he-IL"); - var email = Email - .From(fromEmail) - .To(toEmail) - .Subject(subject) - .UsingCultureTemplateFromFile($"{Path.Combine(Directory.GetCurrentDirectory(), "test.txt")}", new {Test = "FLUENTEMAIL"}, culture); - - email.Data.Body.Should().Be("hebrew email FLUENTEMAIL"); - } - - [Fact] - public void Anonymous_Model_Template_Matches() - { - string template = "sup ##Name##"; - - var email = Email - .From(fromEmail) - .To(toEmail) - .Subject(subject) - .UsingTemplate(template, new { Name = "LUKE" }); - - email.Data.Body.Should().Be("sup LUKE"); - } - - - - [Fact] - public void Set_Custom_Template() - { - string template = "sup ##Name## here is a list @foreach(var i in Model.Numbers) { @i }"; - - var email = Email - .From(fromEmail) - .To(toEmail) - .Subject(subject) - .UsingTemplateEngine(new TestTemplate()) - .UsingTemplate(template, new { Name = "LUKE", Numbers = new string[] { "1", "2", "3" } }); - - email.Data.Body.Should().Be("custom template"); - } - - [Fact] - public void Using_Template_From_Embedded_Resource() - { - var email = Email - .From(fromEmail) - .To(toEmail) - .Subject(subject) - .UsingTemplateFromEmbedded("FluentEmail.Core.Tests.test-embedded.txt", new { Test = "EMBEDDEDTEST" }, ThisAssembly()); - - email.Data.Body.Should().Be("yo email EMBEDDEDTEST"); - } - - [Fact] - public void Using_Template_From_Root_Configured_Embedded_Resource() - { - EmbeddedTemplates.Configure(Assembly.GetExecutingAssembly(), "FluentEmail.Core.Tests"); - var email = Email - .From(fromEmail) - .To(toEmail) - .Subject(subject) - .UsingTemplateFromEmbedded("test-embedded.txt", new { Test = "EMBEDDEDTEST" }); - - email.Data.Body.Should().Be("yo email EMBEDDEDTEST"); - } + private Assembly ThisAssembly() => this.GetType().GetTypeInfo().Assembly; + private const string ToEmail = "bob@test.com"; + private const string FromEmail = "johno@test.com"; + private const string Subject = "sup dawg"; + + [Fact] + public void Anonymous_Model_Template_From_File_Matches() + { + var email = Email + .From(FromEmail) + .To(ToEmail) + .Subject(Subject) + .UsingTemplateFromFile($"{Path.Combine(Directory.GetCurrentDirectory(), "test.txt")}", new { Test = "FLUENT EMAIL" }); + + email.Data.Body.Should().Be("yo email FLUENT EMAIL"); + } + + [Fact] + public void Using_Template_From_Not_Existing_Culture_File_Using_Default_Template() + { + var culture = new CultureInfo("fr-FR"); + var email = Email + .From(FromEmail) + .To(ToEmail) + .Subject(Subject) + .UsingCultureTemplateFromFile($"{Path.Combine(Directory.GetCurrentDirectory(), "test.txt")}", new { Test = "FLUENT EMAIL", culture }, culture); + + email.Data.Body.Should().Be("yo email FLUENT EMAIL"); + } + + [Fact] + public void Using_Template_From_Culture_File() + { + var culture = new CultureInfo("he-IL"); + var email = Email + .From(FromEmail) + .To(ToEmail) + .Subject(Subject) + .UsingCultureTemplateFromFile($"{Path.Combine(Directory.GetCurrentDirectory(), "test.txt")}", new { Test = "FLUENT EMAIL" }, culture); + + email.Data.Body.Should().Be("hebrew email FLUENT EMAIL"); + } + + [Fact] + public void Using_Template_From_Current_Culture_File() + { + var culture = new CultureInfo("he-IL"); + var email = Email + .From(FromEmail) + .To(ToEmail) + .Subject(Subject) + .UsingCultureTemplateFromFile($"{Path.Combine(Directory.GetCurrentDirectory(), "test.txt")}", new {Test = "FLUENT EMAIL"}, culture); + + email.Data.Body.Should().Be("hebrew email FLUENT EMAIL"); + } + + [Fact] + public void Anonymous_Model_Template_Matches() + { + var template = "sup ##Name##"; + + var email = Email + .From(FromEmail) + .To(ToEmail) + .Subject(Subject) + .UsingTemplate(template, new { Name = "LUKE" }); + + email.Data.Body.Should().Be("sup LUKE"); + } + + + + [Fact] + public void Set_Custom_Template() + { + var template = "sup ##Name## here is a list @foreach(var i in Model.Numbers) { @i }"; + + var email = Email + .From(FromEmail) + .To(ToEmail) + .Subject(Subject) + .UsingTemplateEngine(new TestTemplate()) + .UsingTemplate(template, new { Name = "LUKE", Numbers = (string[])["1", "2", "3"] }); + + email.Data.Body.Should().Be("custom template"); + } + + [Fact] + public void Using_Template_From_Embedded_Resource() + { + var email = Email + .From(FromEmail) + .To(ToEmail) + .Subject(Subject) + .UsingTemplateFromEmbedded("FluentEmail.Core.Tests.test-embedded.txt", new { Test = "EMBEDDED TEST" }, ThisAssembly()); + + email.Data.Body.Should().Be("yo email EMBEDDED TEST"); + } + + [Fact] + public void Using_Template_From_Root_Configured_Embedded_Resource() + { + EmbeddedTemplates.Configure(Assembly.GetExecutingAssembly(), "FluentEmail.Core.Tests"); + var email = Email + .From(FromEmail) + .To(ToEmail) + .Subject(Subject) + .UsingTemplateFromEmbedded("test-embedded.txt", new { Test = "EMBEDDED TEST" }); + + email.Data.Body.Should().Be("yo email EMBEDDED TEST"); + } - [Fact] - public void Using_Template_From_Configured_Embedded_Resource() - { - EmbeddedTemplates.Configure(Assembly.GetExecutingAssembly(), "FluentEmail.Core.Tests.EmailTemplates"); - var email = Email - .From(fromEmail) - .To(toEmail) - .Subject(subject) - .UsingTemplateFromEmbedded("test-embedded.txt", new { Test = "EMBEDDEDTEST" }); - - email.Data.Body.Should().Be("yo email EMBEDDEDTEST"); - } + [Fact] + public void Using_Template_From_Configured_Embedded_Resource() + { + EmbeddedTemplates.Configure(Assembly.GetExecutingAssembly(), "FluentEmail.Core.Tests.EmailTemplates"); + var email = Email + .From(FromEmail) + .To(ToEmail) + .Subject(Subject) + .UsingTemplateFromEmbedded("test-embedded.txt", new { Test = "EMBEDDED TEST" }); + + email.Data.Body.Should().Be("yo email EMBEDDED TEST"); + } - [Fact] - public void New_Anonymous_Model_Template_From_File_Matches() - { - var email = new Email(fromEmail) - .To(toEmail) - .Subject(subject) - .UsingTemplateFromFile($"{Path.Combine(Directory.GetCurrentDirectory(), "test.txt")}", new { Test = "FLUENTEMAIL" }); - - email.Data.Body.Should().Be("yo email FLUENTEMAIL"); - } - - [Fact] - public void New_Using_Template_From_Not_Existing_Culture_File_Using_Default_Template() - { - var culture = new CultureInfo("fr-FR"); - var email = new Email(fromEmail) - .To(toEmail) - .Subject(subject) - .UsingCultureTemplateFromFile($"{Path.Combine(Directory.GetCurrentDirectory(), "test.txt")}", new { Test = "FLUENTEMAIL", culture }, culture); - - email.Data.Body.Should().Be("yo email FLUENTEMAIL"); - } - - [Fact] - public void New_Using_Template_From_Culture_File() - { - var culture = new CultureInfo("he-IL"); - var email = new Email(fromEmail) - .To(toEmail) - .Subject(subject) - .UsingCultureTemplateFromFile($"{Path.Combine(Directory.GetCurrentDirectory(), "test.txt")}", new { Test = "FLUENTEMAIL" }, culture); - - email.Data.Body.Should().Be("hebrew email FLUENTEMAIL"); - } - - [Fact] - public void New_Using_Template_From_Current_Culture_File() - { - var culture = new CultureInfo("he-IL"); - var email = new Email(fromEmail) - .To(toEmail) - .Subject(subject) - .UsingCultureTemplateFromFile($"{Path.Combine(Directory.GetCurrentDirectory(), "test.txt")}", new {Test = "FLUENTEMAIL"}, culture); - - email.Data.Body.Should().Be("hebrew email FLUENTEMAIL"); - } - - - - [Fact] - public void New_Set_Custom_Template() - { - string template = "sup @Model.Name here is a list @foreach(var i in Model.Numbers) { @i }"; - - var email = new Email(new TestTemplate(), new SaveToDiskSender("/"), fromEmail) - .To(toEmail) - .Subject(subject) - .UsingTemplate(template, new { Name = "LUKE", Numbers = new string[] { "1", "2", "3" } }); - - email.Data.Body.Should().Be("custom template"); - } - - [Fact] - public void New_Using_Template_From_Embedded_Resource() - { - var email = new Email(fromEmail) - .To(toEmail) - .Subject(subject) - .UsingTemplateFromEmbedded("FluentEmail.Core.Tests.test-embedded.txt", new { Test = "EMBEDDEDTEST" }, ThisAssembly()); - - email.Data.Body.Should().Be("yo email EMBEDDEDTEST"); - } - } - - public class TestTemplate : ITemplateRenderer - { - public string Parse(string template, T model, bool isHtml = true) - { - return "custom template"; - } - - public Task ParseAsync(string template, T model, bool isHtml = true) - { - return Task.FromResult(Parse(template, model, isHtml)); - } - } + [Fact] + public void New_Anonymous_Model_Template_From_File_Matches() + { + var email = new Email(FromEmail) + .To(ToEmail) + .Subject(Subject) + .UsingTemplateFromFile($"{Path.Combine(Directory.GetCurrentDirectory(), "test.txt")}", new { Test = "FLUENT EMAIL" }); + + email.Data.Body.Should().Be("yo email FLUENT EMAIL"); + } + + [Fact] + public void New_Using_Template_From_Not_Existing_Culture_File_Using_Default_Template() + { + var culture = new CultureInfo("fr-FR"); + var email = new Email(FromEmail) + .To(ToEmail) + .Subject(Subject) + .UsingCultureTemplateFromFile($"{Path.Combine(Directory.GetCurrentDirectory(), "test.txt")}", new { Test = "FLUENT EMAIL", culture }, culture); + + email.Data.Body.Should().Be("yo email FLUENT EMAIL"); + } + + [Fact] + public void New_Using_Template_From_Culture_File() + { + var culture = new CultureInfo("he-IL"); + var email = new Email(FromEmail) + .To(ToEmail) + .Subject(Subject) + .UsingCultureTemplateFromFile($"{Path.Combine(Directory.GetCurrentDirectory(), "test.txt")}", new { Test = "FLUENT EMAIL" }, culture); + + email.Data.Body.Should().Be("hebrew email FLUENT EMAIL"); + } + + [Fact] + public void New_Using_Template_From_Current_Culture_File() + { + var culture = new CultureInfo("he-IL"); + var email = new Email(FromEmail) + .To(ToEmail) + .Subject(Subject) + .UsingCultureTemplateFromFile($"{Path.Combine(Directory.GetCurrentDirectory(), "test.txt")}", new {Test = "FLUENT EMAIL"}, culture); + + email.Data.Body.Should().Be("hebrew email FLUENT EMAIL"); + } + + + + [Fact] + public void New_Set_Custom_Template() + { + var template = "sup @Model.Name here is a list @foreach(var i in Model.Numbers) { @i }"; + + var email = new Email(new TestTemplate(), new SaveToDiskSender("/"), FromEmail) + .To(ToEmail) + .Subject(Subject) + .UsingTemplate(template, new { Name = "LUKE", Numbers = (string[])["1", "2", "3"] }); + + email.Data.Body.Should().Be("custom template"); + } + + [Fact] + public void New_Using_Template_From_Embedded_Resource() + { + var email = new Email(FromEmail) + .To(ToEmail) + .Subject(Subject) + .UsingTemplateFromEmbedded("FluentEmail.Core.Tests.test-embedded.txt", new { Test = "EMBEDDED TEST" }, ThisAssembly()); + + email.Data.Body.Should().Be("yo email EMBEDDED TEST"); + } } + +public class TestTemplate : ITemplateRenderer +{ + public string Parse(string template, T model, bool isHtml = true) + { + return "custom template"; + } + + public Task ParseAsync(string template, T model, bool isHtml = true) + { + return Task.FromResult(Parse(template, model, isHtml)); + } +} \ No newline at end of file diff --git a/test/FluentEmail.Core.Tests/ThirdParty/AzureEmailSenderTests.cs b/test/FluentEmail.Core.Tests/ThirdParty/AzureEmailSenderTests.cs new file mode 100644 index 0000000..0068732 --- /dev/null +++ b/test/FluentEmail.Core.Tests/ThirdParty/AzureEmailSenderTests.cs @@ -0,0 +1,133 @@ +using FluentEmail.Azure.Email; + +namespace FluentEmail.Core.Tests.ThirdParty; + +public class AzureEmailSenderTests +{ + private readonly string _toEmail = Credentials.Azure.ToEmail ?? Credentials.ToEmail; + private readonly string _fromEmail = Credentials.Azure.FromEmail ?? Credentials.FromEmail; + private readonly string _connectionString = Credentials.Azure.ApiHost; + + private const string ToName = "FluentEmail tester"; + private const string FromName = "AzureEmailSender Test"; + + private ISender Sender { get; } + + public AzureEmailSenderTests() + { + if (!string.IsNullOrEmpty(_connectionString)) Sender = new AzureEmailSender(_connectionString); + } + + [Fact] + public async Task CanSendEmail() + { + Assert.SkipWhen(string.IsNullOrEmpty(_connectionString), "No Azure Credentials"); + + const string subject = "SendMail Test"; + const string body = "This email is testing send mail functionality of Azure Email Sender."; + + var email = Email + .From(_fromEmail, FromName) + .To(_toEmail, ToName) + .Subject(subject) + .Body(body); + + email.Sender = Sender; + var response = await email.SendAsync(); + + (response.Successful).Should().BeTrue(); + } + + [Fact] + public async Task CanSendEmailWithReplyTo() + { + Assert.SkipWhen(string.IsNullOrEmpty(_connectionString), "No Azure Credentials"); + + const string subject = "SendMail Test"; + const string body = "This email is testing send mail with ReplyTo functionality of Azure Email Sender."; + + var email = Email + .From(_fromEmail, FromName) + .To(_toEmail, ToName) + .ReplyTo(_toEmail, ToName) + .Subject(subject) + .Body(body); + + email.Sender = Sender; + var response = await email.SendAsync(); + + (response.Successful).Should().BeTrue(); + } + + [Fact] + public async Task CanSendEmailWithAttachments() + { + Assert.SkipWhen(string.IsNullOrEmpty(_connectionString), "No Azure Credentials"); + + const string subject = "SendMail With Attachments Test"; + const string body = "This email is testing the attachment functionality of Azure Email Sender."; + + await using var stream = File.OpenRead($"{Directory.GetCurrentDirectory()}/test-binary.xlsx"); + var attachment = new Attachment + { + Data = stream, + ContentType = "xlsx", + Filename = "test-binary.xlsx" + }; + + var email = Email + .From(_fromEmail, FromName) + .To(_toEmail, ToName) + .Subject(subject) + .Body(body) + .Attach(attachment); + + email.Sender = Sender; + + var response = await email.SendAsync(); + + (response.Successful).Should().BeTrue(); + } + + [Fact] + public async Task CanSendHighPriorityEmail() + { + Assert.SkipWhen(string.IsNullOrEmpty(_connectionString), "No Azure Credentials"); + + const string subject = "SendMail Test"; + const string body = "This email is testing send mail functionality of Azure Email Sender."; + + var email = Email + .From(_fromEmail, FromName) + .To(_toEmail, ToName) + .Subject(subject) + .Body(body) + .HighPriority(); + + email.Sender = Sender; + var response = await email.SendAsync(); + + (response.Successful).Should().BeTrue(); + } + + [Fact] + public async Task CanSendLowPriorityEmail() + { + Assert.SkipWhen(string.IsNullOrEmpty(_connectionString), "No Azure Credentials"); + + const string subject = "SendMail Test"; + const string body = "This email is testing send mail functionality of Azure Email Sender."; + + var email = Email + .From(_fromEmail, FromName) + .To(_toEmail, ToName) + .Subject(subject) + .Body(body) + .LowPriority(); + + email.Sender = Sender; + var response = await email.SendAsync(); + + (response.Successful).Should().BeTrue(); + } +} \ No newline at end of file diff --git a/test/FluentEmail.Core.Tests/ThirdParty/GraphSenderTests.cs b/test/FluentEmail.Core.Tests/ThirdParty/GraphSenderTests.cs new file mode 100644 index 0000000..cb86f2a --- /dev/null +++ b/test/FluentEmail.Core.Tests/ThirdParty/GraphSenderTests.cs @@ -0,0 +1,104 @@ +using FluentEmail.Graph; + +namespace FluentEmail.Core.Tests.ThirdParty; + +public class GraphSenderTests +{ + private readonly string _appId = Credentials.Graph.AppId; + private readonly string _tenantId = Credentials.Graph.TenantId; + private readonly string _graphSecret = Credentials.Graph.ClientSecret; + private readonly string _senderEmail = Credentials.Graph.FromEmail ?? Credentials.FromEmail; + private readonly string _toEmail = Credentials.Graph.ToEmail ?? Credentials.ToEmail; + private const bool SaveSent = false; + + private ISender Sender { get; } + + public GraphSenderTests() + { + if (string.IsNullOrWhiteSpace(_appId)) return; + if (string.IsNullOrWhiteSpace(_tenantId)) return; + if (string.IsNullOrWhiteSpace(_graphSecret)) return; + if (string.IsNullOrWhiteSpace(_senderEmail)) return; + + Sender = new GraphSender(_appId, _tenantId, _graphSecret, SaveSent); + } + + [Fact] + public void CanSendEmail() + { + Assert.SkipWhen(string.IsNullOrEmpty(_appId), "No Graph/AD Credentials"); + + var email = Email + .From(_senderEmail) + .To(_toEmail) + .Subject("Test Email") + .Body("Test email from Graph sender unit test"); + + email.Sender = Sender; + var response = email.Send(); + (response.Successful).Should().BeTrue(); + } + + [Fact] + public async Task CanSendEmailAsync() + { + Assert.SkipWhen(string.IsNullOrEmpty(_appId), "No Graph/AD Credentials"); + + var email = Email + .From(_senderEmail) + .To(_toEmail) + .Subject("Test Async Email") + .Body("Test email from Graph sender unit test"); + + email.Sender = Sender; + var response = await email.SendAsync(); + (response.Successful).Should().BeTrue(); + } + + [Fact] + public async Task CanSendEmailWithAttachments() + { + Assert.SkipWhen(string.IsNullOrEmpty(_appId), "No Graph/AD Credentials"); + + var stream = new MemoryStream(); + var sw = new StreamWriter(stream); + await sw.WriteLineAsync("Hey this is some text in an attachment"); + await sw.FlushAsync(TestContext.Current.CancellationToken); + stream.Seek(0, SeekOrigin.Begin); + + var attachment = new Attachment + { + ContentType = "text/plain", + Filename = "graphtest.txt", + Data = stream + }; + + var email = Email + .From(_senderEmail) + .To(_toEmail) + .Subject("Test Email with Attachments") + .Body("Test email from Graph sender unit test") + .Attach(attachment); + + email.Sender = Sender; + var response = await email.SendAsync(); + (response.Successful).Should().BeTrue(); + } + + [Fact] + public async Task CanSendHighPriorityEmail() + { + Assert.SkipWhen(string.IsNullOrEmpty(_appId), "No Graph/AD Credentials"); + + var email = Email + .From(_senderEmail) + .To(_toEmail) + .Subject("Test High Priority Email") + .Body("Test email from Graph sender unit test") + .HighPriority(); + + email.Sender = Sender; + var response = await email.SendAsync(); + (response.Successful).Should().BeTrue(); + } +} \ No newline at end of file diff --git a/test/FluentEmail.Core.Tests/ThirdParty/MailgunSenderTests.cs b/test/FluentEmail.Core.Tests/ThirdParty/MailgunSenderTests.cs new file mode 100644 index 0000000..f351a8e --- /dev/null +++ b/test/FluentEmail.Core.Tests/ThirdParty/MailgunSenderTests.cs @@ -0,0 +1,174 @@ +using FluentEmail.Mailgun; +using Newtonsoft.Json; + +namespace FluentEmail.Core.Tests.ThirdParty; + +public class MailgunSenderTests +{ + private readonly string _toEmail = Credentials.Mailgun.ToEmail ?? Credentials.ToEmail; + private readonly string _fromEmail = Credentials.Mailgun.FromEmail ?? Credentials.FromEmail; + private readonly string _apiKey = Credentials.Mailgun.ApiKey; + private readonly string _domain = Credentials.Mailgun.Domain; + private const string Subject = "Attachment Tests"; + private const string Body = "This email is testing the attachment functionality of MailGun."; + + private ISender Sender { get; } + + public MailgunSenderTests() + { + if (!string.IsNullOrEmpty(_apiKey)) Sender = new MailgunSender(_domain, _apiKey); + } + + [Fact] + public async Task CanSendEmail() + { + Assert.SkipWhen(string.IsNullOrEmpty(_apiKey), "No Mailgun Credentials"); + + var email = Email + .From(_fromEmail) + .To(_toEmail) + .Subject(Subject) + .Body(Body); + + email.Sender = Sender; + var response = await email.SendAsync(); + + (response.Successful).Should().BeTrue(); + } + + [Fact] + public async Task GetMessageIdInResponse() + { + Assert.SkipWhen(string.IsNullOrEmpty(_apiKey), "No Mailgun Credentials"); + + var email = Email + .From(_fromEmail) + .To(_toEmail) + .Subject(Subject) + .Body(Body); + + email.Sender = Sender; + var response = await email.SendAsync(); + + (response.Successful).Should().BeTrue(); + (response.MessageId).Should().NotBeEmpty(); + } + + [Fact] + public async Task CanSendEmailWithTag() + { + Assert.SkipWhen(string.IsNullOrEmpty(_apiKey), "No Mailgun Credentials"); + + var email = Email + .From(_fromEmail) + .To(_toEmail) + .Subject(Subject) + .Body(Body) + .Tag("test"); + + email.Sender = Sender; + var response = await email.SendAsync(); + + (response.Successful).Should().BeTrue(); + } + + [Fact] + public async Task CanSendEmailWithVariables() + { + Assert.SkipWhen(string.IsNullOrEmpty(_apiKey), "No Mailgun Credentials"); + + var email = Email + .From(_fromEmail) + .To(_toEmail) + .Subject(Subject) + .Body(Body) + .Header("X-Mailgun-Variables", JsonConvert.SerializeObject(new Variable { Var1 = "Test"})); + + email.Sender = Sender; + var response = await email.SendAsync(); + + (response.Successful).Should().BeTrue(); + } + + [Fact] + public async Task CanSendEmailWithAttachments() + { + Assert.SkipWhen(string.IsNullOrEmpty(_apiKey), "No Mailgun Credentials"); + + var stream = new MemoryStream(); + var sw = new StreamWriter(stream); + await sw.WriteLineAsync("Hey this is some text in an attachment"); + await sw.FlushAsync(TestContext.Current.CancellationToken); + stream.Seek(0, SeekOrigin.Begin); + + var attachment = new Attachment + { + Data = stream, + ContentType = "text/plain", + Filename = "mailgunTest.txt" + }; + + var email = Email + .From(_fromEmail) + .To(_toEmail) + .Subject(Subject) + .Body(Body) + .Attach(attachment); + + email.Sender = Sender; + var response = await email.SendAsync(); + + (response.Successful).Should().BeTrue(); + } + + [Fact] + public async Task CanSendEmailWithInlineImages() + { + Assert.SkipWhen(string.IsNullOrEmpty(_apiKey), "No Mailgun Credentials"); + + await using var stream = File.OpenRead($"{Path.Combine(Directory.GetCurrentDirectory(), "logotest.png")}"); + var attachment = new Attachment + { + IsInline = true, + Data = stream, + ContentType = "image/png", + Filename = "logotest.png" + }; + + var email = Email + .From(_fromEmail) + .To(_toEmail) + .Subject(Subject) + .Body("Inline image here: " + + "

You should see an image without an attachment, or without a download prompt, depending on the email client.

", true) + .Attach(attachment); + + email.Sender = Sender; + var response = await email.SendAsync(); + + (response.Successful).Should().BeTrue(); + } + + [Fact] + public async Task CanSendEmailWithTemplate() + { + Assert.SkipWhen(string.IsNullOrEmpty(_apiKey), "No Mailgun Credentials"); + Assert.SkipWhen(string.IsNullOrEmpty(Credentials.Mailgun.Template), "No Mailgun Template"); + + var email = Email + .From(_fromEmail) + .To(_toEmail) + .Subject(Subject); + + email.Sender = Sender; + var response = await email.SendWithTemplateAsync("test-template", new { var1 = "Test" }); + + (response.Successful).Should().BeTrue(); + } + + private class Variable + { + // ReSharper disable once UnusedAutoPropertyAccessor.Local + public string Var1 { get; set; } + } +} \ No newline at end of file diff --git a/test/FluentEmail.Core.Tests/ThirdParty/MailtrapSenderTests.cs b/test/FluentEmail.Core.Tests/ThirdParty/MailtrapSenderTests.cs new file mode 100644 index 0000000..833ccc0 --- /dev/null +++ b/test/FluentEmail.Core.Tests/ThirdParty/MailtrapSenderTests.cs @@ -0,0 +1,134 @@ +using FluentEmail.Mailtrap; + +namespace FluentEmail.Core.Tests.ThirdParty; + +public class MailtrapSenderTests +{ + private const string Subject = "Mailtrap Email Test"; + private const string Body = "This email is testing the functionality of mailtrap."; + + private readonly string _toEmail = Credentials.MailTrap.ToEmail ?? Credentials.ToEmail; + private readonly string _fromEmail = Credentials.MailTrap.FromEmail ?? Credentials.FromEmail; + private readonly string _host = Credentials.MailTrap.Host; + private readonly string _username = Credentials.MailTrap.User; + private readonly int _port = Credentials.MailTrap.Port ?? 587; + private readonly string _password = Credentials.MailTrap.Password; + private readonly string _apiHost = Credentials.MailTrap.ApiHost; + private readonly string _apiKey = Credentials.MailTrap.ApiKey; + private readonly string _templateId = Credentials.MailTrap.Template; + + private ISender Sender { get; } + + public MailtrapSenderTests() + { + if (!string.IsNullOrEmpty(_username)) Sender = new MailtrapSender(_username, _password, _host, _port); + } + + [Fact] + public void CanSendEmail() + { + Assert.SkipWhen(string.IsNullOrEmpty(_password), "No Mailtrap Credentials"); + + var email = Email + .From(_fromEmail) + .To(_toEmail) + .Subject(Subject) + .Body(Body); + + email.Sender = Sender; + var response = email.Send(); + + (response.Successful).Should().BeTrue(); + } + + + [Fact] + public async Task CanSendEmailAsync() + { + Assert.SkipWhen(string.IsNullOrEmpty(_password), "No Mailtrap Credentials"); + + var email = Email + .From(_fromEmail) + .To(_toEmail) + .Subject(Subject) + .Body(Body); + + email.Sender = Sender; + var response = await email.SendAsync(); + + (response.Successful).Should().BeTrue(); + } + + [Fact] + public async Task CanSendEmailWithAttachments() + { + Assert.SkipWhen(string.IsNullOrEmpty(_password), "No Mailtrap Credentials"); + + var stream = new MemoryStream(); + var sw = new StreamWriter(stream); + await sw.WriteLineAsync("Hey this is some text in an attachment"); + await sw.FlushAsync(TestContext.Current.CancellationToken); + stream.Seek(0, SeekOrigin.Begin); + + var attachment = new Attachment + { + Data = stream, + ContentType = "text/plain", + Filename = "mailtrapTest.txt" + }; + + var email = Email + .From(_fromEmail) + .To(_toEmail) + .Subject(Subject) + .Body(Body) + .Attach(attachment); + + email.Sender = Sender; + var response = await email.SendAsync(); + + (response.Successful).Should().BeTrue(); + } + + [Fact] + public async Task CanSendEmailWithInlineImages() + { + Assert.SkipWhen(string.IsNullOrEmpty(_password), "No Mailtrap Credentials"); + + await using var stream = File.OpenRead($"{Path.Combine(Directory.GetCurrentDirectory(), "logotest.png")}"); + var attachment = new Attachment + { + IsInline = true, + Data = stream, + ContentType = "image/png", + Filename = "logotest.png" + }; + + var email = Email + .From(_fromEmail) + .To(_toEmail) + .Subject(Subject) + .Body("Inline image here: " + + "

You should see an image without an attachment, or without a download prompt, depending on the email client.

", true) + .Attach(attachment); + + email.Sender = Sender; + var response = await email.SendAsync(); + + (response.Successful).Should().BeTrue(); + } + + [Fact] + public async Task CanSendEmailWithTemplate() + { + Assert.SkipWhen(string.IsNullOrEmpty(_apiKey), "No Mailtrap Credentials"); + + var email = Email.From(_fromEmail).To(_toEmail); + email.Sender = new MailtrapSender(_username, _apiKey, _host, 587, _apiHost); + + // ReSharper disable once StringLiteralTypo + var response = await email.SendWithTemplateAsync(_templateId, new { var1 = "Test", var2 = "VVVVVVVVVVVVV" }); + + (response.Successful).Should().BeTrue(); + } +} \ No newline at end of file diff --git a/test/FluentEmail.Core.Tests/ThirdParty/PostmarkSenderTests.cs b/test/FluentEmail.Core.Tests/ThirdParty/PostmarkSenderTests.cs new file mode 100644 index 0000000..adcd092 --- /dev/null +++ b/test/FluentEmail.Core.Tests/ThirdParty/PostmarkSenderTests.cs @@ -0,0 +1,326 @@ +using FluentEmail.Postmark; +using System.Collections.Generic; + +namespace FluentEmail.Core.Tests.ThirdParty; + +public class PostmarkSenderTests +{ + private readonly string _apiKey = Credentials.Postmark.ApiKey; + + private const string ToEmail = "test@blackhole.postmarkapp.com"; + private const string ToEmailHash = "test+test@blackhole.postmarkapp.com"; + private const string ToEmailHash2 = "test+second@blackhole.postmarkapp.com"; + private readonly string _fromEmail = Credentials.Postmark.FromEmail ?? Credentials.FromEmail; + private const string FromName = "from name"; + private readonly string _fromEmailHash = Credentials.Postmark.FromEmail ?? Credentials.FromEmail; + + private ISender Sender { get; } + + public PostmarkSenderTests() + { + if (!string.IsNullOrEmpty(_apiKey)) Sender = new PostmarkSender(_apiKey); + } + + [Fact] + public void SimpleMailFromCodeSync() + { + Assert.SkipWhen(string.IsNullOrEmpty(_apiKey), "No Postmark Credentials"); + + var email = Email + .From(_fromEmail, FromName) + .To(ToEmail) + .Subject("hows it going bob") + .Body("Whats up?"); + + email.Sender = Sender; + + var response = email.Send(); + + response.Successful.Should().BeTrue(); + } + + [Fact] + public async Task SimpleMailFromCode() + { + Assert.SkipWhen(string.IsNullOrEmpty(_apiKey), "No Postmark Credentials"); + + Email.DefaultSender = new PostmarkSender(_apiKey); + + var email = Email + .From(_fromEmail) + .To(ToEmail) + .Subject("hows it going bob") + .Body("Whats up?"); + + email.Sender = Sender; + + var response = await email.SendAsync(); + + response.Successful.Should().BeTrue(); + response.MessageId.Should().NotBeNullOrEmpty(); + response.ErrorMessages.Should().BeEmpty(); + } + + [Fact] + public async Task SimpleMailFromCodeWithAddressesWithPlus() + { + Assert.SkipWhen(string.IsNullOrEmpty(_apiKey), "No Postmark Credentials"); + + var email = Email + .From(_fromEmailHash) + .To(ToEmailHash) + .ReplyTo(ToEmailHash2) + .Subject("hows it going bob") + .Body("Whats up?"); + + email.Sender = Sender; + var response = await email.SendAsync(); + + response.Successful.Should().BeTrue(); + response.MessageId.Should().NotBeNullOrEmpty(); + response.ErrorMessages.Should().BeEmpty(); + } + + [Fact] + public async Task SimpleMailReplyTo() + { + Assert.SkipWhen(string.IsNullOrEmpty(_apiKey), "No Postmark Credentials"); + + var email = Email + .From(_fromEmail) + .To(ToEmail) + .ReplyTo(_fromEmail) + .Subject("hows it going bob") + .Body("Whats up?"); + + email.Sender = Sender; + var response = await email.SendAsync(); + + response.Successful.Should().BeTrue(); + response.MessageId.Should().NotBeNullOrEmpty(); + response.ErrorMessages.Should().BeEmpty(); + } + + [Fact] + public async Task SimpleMailWithNameFromCode() + { + Assert.SkipWhen(string.IsNullOrEmpty(_apiKey), "No Postmark Credentials"); + + var email = Email + .From(_fromEmail, FromName) + .To(ToEmail) + .Subject("hows it going bob") + .Body("Whats up?"); + + email.Sender = Sender; + var response = await email.SendAsync(); + + response.Successful.Should().BeTrue(); + response.MessageId.Should().NotBeNullOrEmpty(); + response.ErrorMessages.Should().BeEmpty(); + } + + [Fact] + public async Task SimpleHtmlMailFromCode() + { + Assert.SkipWhen(string.IsNullOrEmpty(_apiKey), "No Postmark Credentials"); + + Email.DefaultSender = new PostmarkSender(_apiKey); + + var email = Email + .From(_fromEmail, FromName) + .To(ToEmail) + .Subject("hows it going bob") + .Body("

Test

", true); + + email.Sender = Sender; + var response = await email.SendAsync(); + + response.Successful.Should().BeTrue(); + } + + [Fact] + public async Task SimpleMailWithAttachmentFromCode() + { + Assert.SkipWhen(string.IsNullOrEmpty(_apiKey), "No Postmark Credentials"); + + Email.DefaultSender = new PostmarkSender(_apiKey); + + var email = Email + .From(_fromEmail, FromName) + .To(ToEmail) + .Subject("hows it going bob") + .Body("Whats up?") + .Attach(new Attachment() + { + Filename = "test.txt", + Data = new MemoryStream([0, 1, 2, 3, 4, 5, 6, 7]), + ContentType = "application/octet-stream" + }); + + email.Sender = Sender; + var response = await email.SendAsync(); + + response.Successful.Should().BeTrue(); + response.MessageId.Should().NotBeNullOrEmpty(); + response.ErrorMessages.Should().BeEmpty(); + } + + [Fact] + public async Task SimpleHtmlMailWithAlternateFromCode() + { + Assert.SkipWhen(string.IsNullOrEmpty(_apiKey), "No Postmark Credentials"); + + Email.DefaultSender = new PostmarkSender(_apiKey); + + var email = Email + .From(_fromEmail, FromName) + .To(ToEmail) + .Subject("hows it going bob") + .Body("

Test

", true) + .PlaintextAlternativeBody("Test"); + + email.Sender = Sender; + var response = await email.SendAsync(); + + response.Successful.Should().BeTrue(); + } + + [Fact] + public async Task SimpleMailFromCodeWithOpts() + { + Assert.SkipWhen(string.IsNullOrEmpty(_apiKey), "No Postmark Credentials"); + + var opts = new PostmarkSenderOptions(_apiKey) + { + TrackOpens = true, + TrackLinks = PostmarkDotNet.LinkTrackingOptions.HtmlAndText, + Tag = "unittest", + Metadata = new Dictionary() { { "key", "example" } } + }; + var sender = new PostmarkSender(opts); + + var email = Email + .From(_fromEmail, FromName) + .To(ToEmail) + .Subject("hows it going bob") + .Body("Whats up?"); + + email.Sender = sender; + var response = await email.SendAsync(); + + response.Successful.Should().BeTrue(); + } + + [Fact] + public async Task SimpleMailFromCodeWithLowPriority() + { + Assert.SkipWhen(string.IsNullOrEmpty(_apiKey), "No Postmark Credentials"); + + var email = Email + .From(_fromEmail, FromName) + .To(ToEmail) + .Subject("hows it going bob") + .Body("Whats up?") + .LowPriority(); + + email.Sender = Sender; + var response = await email.SendAsync(); + + response.Successful.Should().BeTrue(); + } + + [Fact] + public async Task SimpleMailFromCodeWithHighPriority() + { + Assert.SkipWhen(string.IsNullOrEmpty(_apiKey), "No Postmark Credentials"); + + var email = Email + .From(_fromEmail, FromName) + .To(ToEmail) + .Subject("hows it going bob") + .Body("Whats up?") + .HighPriority(); + + email.Sender = Sender; + var response = await email.SendAsync(); + + response.Successful.Should().BeTrue(); + } + + [Fact] + public async Task SimpleMailFromCodeWithHeaders() + { + Assert.SkipWhen(string.IsNullOrEmpty(_apiKey), "No Postmark Credentials"); + + var email = Email + .From(_fromEmail, FromName) + .To(ToEmail) + .Subject("hows it going bob") + .Body("Whats up?") + .Header("X-Random-Useless-Header", "SomeValue") + .Header("X-Another-Random-Useless-Header", "AnotherValue"); + + email.Sender = Sender; + var response = await email.SendAsync(); + + response.Successful.Should().BeTrue(); + } + + [Fact] + public void SenderNullServerToken() + { + Assert.SkipWhen(string.IsNullOrEmpty(_apiKey), "No Postmark Credentials"); + var fn = () => new PostmarkSender((string)null!); + fn.Should().Throw(); + } + + [Fact] + public void OptionsNullServerToken() + { + Assert.SkipWhen(string.IsNullOrEmpty(_apiKey), "No Postmark Credentials"); + var fn = () => new PostmarkSenderOptions(null!); + fn.Should().Throw(); + } + + [Fact] + public void NullOptions() + { + Assert.SkipWhen(string.IsNullOrEmpty(_apiKey), "No Postmark Credentials"); + var fn = () => new PostmarkSender((PostmarkSenderOptions)null!); + fn.Should().Throw(); + } + + [Fact] + public void SendNull() + { + Assert.SkipWhen(string.IsNullOrEmpty(_apiKey), "No Postmark Credentials"); + var sender = new PostmarkSender(_apiKey); + Func fn = async () => await sender.SendAsync(null!).ConfigureAwait(false); + fn.Should().ThrowAsync(); + } + + [Fact] + public async Task TooManyRecipients() + { + Assert.SkipWhen(string.IsNullOrEmpty(_apiKey), "No Postmark Credentials"); + + var email = Email + .From(_fromEmail, FromName) + .Subject("hows it going bob") + .Body("Whats up?"); + + email.Sender = Sender; + + var recipientAddresses = new List(); + for (var i = 0; i < 60; i++) + // ReSharper disable twice StringLiteralTypo + recipientAddresses.Add($"test{i}@blackhole.postmarkapp.com"); + + var recipients = recipientAddresses.Select(s => new Address(s)).ToList(); + email.To(recipients); + + var act = async () => { await email.SendAsync(); }; + await act.Should().ThrowAsync(); + } +} \ No newline at end of file diff --git a/test/FluentEmail.Core.Tests/ThirdParty/SendGridSenderTests.cs b/test/FluentEmail.Core.Tests/ThirdParty/SendGridSenderTests.cs new file mode 100644 index 0000000..a823a86 --- /dev/null +++ b/test/FluentEmail.Core.Tests/ThirdParty/SendGridSenderTests.cs @@ -0,0 +1,218 @@ +using FluentEmail.SendGrid; + +namespace FluentEmail.Core.Tests.ThirdParty; + +public class SendGridSenderTests +{ + private readonly string _apiKey = Credentials.SendGrid.ApiKey; + private readonly string _toEmail = Credentials.SendGrid.ToEmail ?? Credentials.ToEmail; + private readonly string _fromEmail = Credentials.SendGrid.FromEmail ?? Credentials.FromEmail; + + private const string ToName = "FluentEmail Test"; + private const string FromName = "SendGridSender Test"; + + private ISender Sender { get; } + + public SendGridSenderTests() + { + if (!string.IsNullOrEmpty(_apiKey)) Sender = new SendGridSender(_apiKey, true); + } + + [Fact] + public async Task CanSendEmail() + { + Assert.SkipWhen(string.IsNullOrEmpty(_apiKey), "No SendGrid Credentials"); + + const string subject = "SendMail Test"; + const string body = "This email is testing send mail functionality of SendGrid Sender."; + + var email = Email + .From(_fromEmail, FromName) + .To(_toEmail, ToName) + .Subject(subject) + .Body(body); + + email.Sender = Sender; + + var response = await email.SendAsync(); + + (response.Successful).Should().BeTrue(); + } + + [Fact] + public async Task CanSendTemplateEmail() + { + Assert.SkipWhen(string.IsNullOrEmpty(_apiKey), "No SendGrid Credentials"); + + const string subject = "SendMail Test"; + var templateId = Credentials.SendGrid.Template; + object templateData = new + { + Name = ToName, + ArbitraryValue = "The quick brown fox jumps over the lazy dog." + }; + + var email = Email + .From(_fromEmail, FromName) + .To(_toEmail, ToName) + .Subject(subject); + + email.Sender = Sender; + + var response = await email.SendWithTemplateAsync(templateId, templateData); + + (response.Successful).Should().BeTrue(); + } + + [Fact] + public async Task CanSendEmailWithReplyTo() + { + Assert.SkipWhen(string.IsNullOrEmpty(_apiKey), "No SendGrid Credentials"); + + const string subject = "SendMail Test"; + const string body = "This email is testing send mail with ReplyTo functionality of SendGrid Sender."; + + var email = Email + .From(_fromEmail, FromName) + .To(_toEmail, ToName) + .ReplyTo(_toEmail, ToName) + .Subject(subject) + .Body(body); + + email.Sender = Sender; + + var response = await email.SendAsync(); + + (response.Successful).Should().BeTrue(); + } + + [Fact] + public async Task CanSendEmailWithCategory() + { + Assert.SkipWhen(string.IsNullOrEmpty(_apiKey), "No SendGrid Credentials"); + + const string subject = "SendMail Test"; + const string body = "This email is testing send mail with Categories functionality of SendGrid Sender."; + + var email = Email + .From(_fromEmail, FromName) + .To(_toEmail, ToName) + .ReplyTo(_toEmail, ToName) + .Subject(subject) + .Tag("TestCategory") + .Body(body); + + email.Sender = Sender; + + var response = await email.SendAsync(); + + (response.Successful).Should().BeTrue(); + } + + [Fact] + public async Task CanSendEmailWithAttachments() + { + Assert.SkipWhen(string.IsNullOrEmpty(_apiKey), "No SendGrid Credentials"); + + const string subject = "SendMail With Attachments Test"; + const string body = "This email is testing the attachment functionality of SendGrid Sender."; + + await using var stream = File.OpenRead($"{Directory.GetCurrentDirectory()}/test-binary.xlsx"); + var attachment = new Attachment + { + Data = stream, + // ReSharper disable twice StringLiteralTypo + ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + Filename = "test-binary.xlsx" + }; + + var email = Email + .From(_fromEmail, FromName) + .To(_toEmail, ToName) + .Subject(subject) + .Body(body) + .Attach(attachment); + + email.Sender = Sender; + + var response = await email.SendAsync(); + + (response.Successful).Should().BeTrue(); + } + + [Fact] + public async Task CanSendHighPriorityEmail() + { + Assert.SkipWhen(string.IsNullOrEmpty(_apiKey), "No SendGrid Credentials"); + + const string subject = "SendMail Test"; + const string body = "This email is testing send mail functionality of SendGrid Sender."; + + var email = Email + .From(_fromEmail, FromName) + .To(_toEmail, ToName) + .Subject(subject) + .Body(body) + .HighPriority(); + + email.Sender = Sender; + + var response = await email.SendAsync(); + + (response.Successful).Should().BeTrue(); + } + + [Fact] + public async Task CanSendLowPriorityEmail() + { + Assert.SkipWhen(string.IsNullOrEmpty(_apiKey), "No SendGrid Credentials"); + + const string subject = "SendMail Test"; + const string body = "This email is testing send mail functionality of SendGrid Sender."; + + var email = Email + .From(_fromEmail, FromName) + .To(_toEmail, ToName) + .Subject(subject) + .Body(body) + .LowPriority(); + + email.Sender = Sender; + + var response = await email.SendAsync(); + + (response.Successful).Should().BeTrue(); + } + + [Fact] + public async Task CanSendEmailWithInlineAttachments() + { + Assert.SkipWhen(string.IsNullOrEmpty(_apiKey), "No SendGrid Credentials"); + + // Arrange + const string subject = "SendMail With Inline Attachments Test"; + const string body = "This email is testing the inline attachment functionality of SendGrid Sender."; + + await using var stream = File.OpenRead($"{Directory.GetCurrentDirectory()}/logotest.png"); + var attachment = new Attachment + { + Data = stream, + ContentType = "image/png", + Filename = "logotest.png", + IsInline = true, + ContentId = "logotest_id" + }; + + var email = Email + .From(_fromEmail, FromName) + .To(_toEmail, ToName) + .Subject(subject) + .Body(body) + .Attach(attachment); + + email.Sender = Sender; + var response = await email.SendAsync(); + + (response.Successful).Should().BeTrue(); + } +} \ No newline at end of file diff --git a/test/FluentEmail.Core.Tests/_Credentials.cs b/test/FluentEmail.Core.Tests/_Credentials.cs new file mode 100644 index 0000000..5b7193c --- /dev/null +++ b/test/FluentEmail.Core.Tests/_Credentials.cs @@ -0,0 +1,53 @@ +using dotenv.net; +using dotenv.net.Utilities; + +namespace FluentEmail.Core.Tests; + +internal static class Credentials +{ + public static TestCredentials MailTrap => new ("MAILTRAP"); + public static MailgunCredentials Mailgun => new("MAILGUN"); + public static TestCredentials Azure => new ("AZURE"); + public static TestCredentials Postmark => new("POSTMARK"); + public static TestCredentials SendGrid => new("SENDGRID"); + public static GraphCredentials Graph => new("GRAPH"); + + public static string ToEmail; + public static string FromEmail; + + static Credentials() + { + DotEnv.Load(); + ToEmail = GetDotEnvString("FE_TEST_TO_EMAIL"); + FromEmail = GetDotEnvString("FE_TEST_FROM_EMAIL"); + } + + public static string GetDotEnvString(string key) => EnvReader.TryGetStringValue(key, out var value) ? value : null; + + public static int? GetDotEnvInt(string key) => EnvReader.TryGetIntValue(key, out var value) ? value : null; +} + +internal class TestCredentials(string keyBase) +{ + public string Host { get; private set; } = Credentials.GetDotEnvString($"FE_TEST_{keyBase}_HOST"); + public string User { get; private set; } = Credentials.GetDotEnvString($"FE_TEST_{keyBase}_USER"); + public string Password { get; private set; } = Credentials.GetDotEnvString($"FE_TEST_{keyBase}_PWD"); + public int? Port { get; private set; } = Credentials.GetDotEnvInt($"FE_TEST_{keyBase}_PORT") ?? 587; + public string ApiKey { get; private set; } = Credentials.GetDotEnvString($"FE_TEST_{keyBase}_API_KEY"); + public string ApiHost { get; private set; } = Credentials.GetDotEnvString($"FE_TEST_{keyBase}_API_HOST"); + public string Template { get; private set; } = Credentials.GetDotEnvString($"FE_TEST_{keyBase}_TEMPLATE"); + public string FromEmail { get; private set; } = Credentials.GetDotEnvString($"FE_TEST_{keyBase}_FROM_EMAIL"); + public string ToEmail { get; private set; } = Credentials.GetDotEnvString($"FE_TEST_{keyBase}_TO_EMAIL"); +} + +internal class MailgunCredentials(string keyBase) : TestCredentials(keyBase) +{ + public string Domain { get; set; } = Credentials.GetDotEnvString($"FE_TEST_{keyBase}_DOMAIN"); +} + +internal class GraphCredentials(string keyBase) : TestCredentials(keyBase) +{ + public string AppId { get; set; } = Credentials.GetDotEnvString($"FE_TEST_{keyBase}_APP_ID"); + public string TenantId { get; set; } = Credentials.GetDotEnvString($"FE_TEST_{keyBase}_TENANT_ID"); + public string ClientSecret { get; set; } = Credentials.GetDotEnvString($"FE_TEST_{keyBase}_CLIENT_SECRET"); +} \ No newline at end of file diff --git a/test/FluentEmail.Liquid.Tests/ComplexModel/ComplexModelRenderTests.cs b/test/FluentEmail.Liquid.Tests/ComplexModel/ComplexModelRenderTests.cs index bde9b5d..6621729 100644 --- a/test/FluentEmail.Liquid.Tests/ComplexModel/ComplexModelRenderTests.cs +++ b/test/FluentEmail.Liquid.Tests/ComplexModel/ComplexModelRenderTests.cs @@ -1,7 +1,8 @@ using System; -using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using AwesomeAssertions; using FluentEmail.Core; +using FluentEmail.Core.Interfaces; using Fluid; using Microsoft.Extensions.FileProviders; using Microsoft.Extensions.Options; @@ -11,22 +12,17 @@ namespace FluentEmail.Liquid.Tests.ComplexModel { public class ComplexModelRenderTests { - public ComplexModelRenderTests() - { - SetupRenderer(); - } - [Fact] public void Can_Render_Complex_Model_Properties() { var model = new ParentModel { ParentName = new NameDetails { Firstname = "Luke", Surname = "Dinosaur" }, - ChildrenNames = new List - { + ChildrenNames = + [ new NameDetails { Firstname = "ChildFirstA", Surname = "ChildLastA" }, new NameDetails { Firstname = "ChildFirstB", Surname = "ChildLastB" } - } + ] }; var expected = @" @@ -40,11 +36,16 @@ public void Can_Render_Complex_Model_Properties() var email = Email .From(TestData.FromEmail) .To(TestData.ToEmail) - .Subject(TestData.Subject) - .UsingTemplate(Template(), model); + .Subject(TestData.Subject); + + email.Renderer = SetupRenderer(); + + email.UsingTemplate(Template(), model); + email.Data.Body.Should().Be(expected); } + [SuppressMessage("ReSharper", "StringLiteralTypo")] private string Template() { return @" @@ -55,7 +56,7 @@ private string Template() "; } - private static void SetupRenderer( + private static ITemplateRenderer SetupRenderer( IFileProvider fileProvider = null, Action configureTemplateContext = null) { @@ -65,7 +66,7 @@ private static void SetupRenderer( ConfigureTemplateContext = configureTemplateContext, TemplateOptions = new TemplateOptions { MemberAccessStrategy = new UnsafeMemberAccessStrategy() } }; - Email.DefaultRenderer = new LiquidRenderer(Options.Create(options)); + return new LiquidRenderer(Options.Create(options)); } } } \ No newline at end of file diff --git a/test/FluentEmail.Liquid.Tests/ComplexModel/ParentModel.cs b/test/FluentEmail.Liquid.Tests/ComplexModel/ParentModel.cs index 029f344..8a1ece4 100644 --- a/test/FluentEmail.Liquid.Tests/ComplexModel/ParentModel.cs +++ b/test/FluentEmail.Liquid.Tests/ComplexModel/ParentModel.cs @@ -1,17 +1,16 @@ using System.Collections.Generic; -namespace FluentEmail.Liquid.Tests +namespace FluentEmail.Liquid.Tests.ComplexModel; + +public class ParentModel { - public class ParentModel - { - public string Id { get; set; } - public NameDetails ParentName { get; set; } - public List ChildrenNames { get; set; } = new List(); - } + public string Id { get; set; } + public NameDetails ParentName { get; set; } + public List ChildrenNames { get; set; } = []; +} - public class NameDetails - { - public string Firstname { get; set; } - public string Surname { get; set; } - } +public class NameDetails +{ + public string Firstname { get; set; } + public string Surname { get; set; } } \ No newline at end of file diff --git a/test/FluentEmail.Liquid.Tests/ComplexModel/TestData.cs b/test/FluentEmail.Liquid.Tests/ComplexModel/TestData.cs index e1dd598..2f19cc9 100644 --- a/test/FluentEmail.Liquid.Tests/ComplexModel/TestData.cs +++ b/test/FluentEmail.Liquid.Tests/ComplexModel/TestData.cs @@ -1,9 +1,8 @@ -namespace FluentEmail.Liquid.Tests +namespace FluentEmail.Liquid.Tests.ComplexModel; + +public static class TestData { - public static class TestData - { - public const string ToEmail = "bob@test.com"; - public const string FromEmail = "johno@test.com"; - public const string Subject = "sup dawg"; - } + public const string ToEmail = "bob@test.com"; + public const string FromEmail = "johno@test.com"; + public const string Subject = "sup dawg"; } \ No newline at end of file diff --git a/test/FluentEmail.Liquid.Tests/FluentEmail.Liquid.Tests.csproj b/test/FluentEmail.Liquid.Tests/FluentEmail.Liquid.Tests.csproj index bf5d967..7e40f6a 100644 --- a/test/FluentEmail.Liquid.Tests/FluentEmail.Liquid.Tests.csproj +++ b/test/FluentEmail.Liquid.Tests/FluentEmail.Liquid.Tests.csproj @@ -1,7 +1,6 @@  - net8.0 true @@ -19,9 +18,8 @@ - + - diff --git a/test/FluentEmail.Liquid.Tests/LiquidTests.cs b/test/FluentEmail.Liquid.Tests/LiquidTests.cs index ef3658a..ddcbb4e 100644 --- a/test/FluentEmail.Liquid.Tests/LiquidTests.cs +++ b/test/FluentEmail.Liquid.Tests/LiquidTests.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Reflection; using System.Text.Encodings.Web; @@ -14,6 +15,7 @@ using Xunit; using AwesomeAssertions; +using FluentEmail.Core.Interfaces; namespace FluentEmail.Liquid.Tests { @@ -23,13 +25,7 @@ public class LiquidTests private const string FromEmail = "johno@test.com"; private const string Subject = "sup dawg"; - public LiquidTests() - { - // default to have no file provider, only required when layout files are in use - SetupRenderer(); - } - - private static void SetupRenderer( + private static ITemplateRenderer SetupRenderer( IFileProvider fileProvider = null, Action configureTemplateContext = null, Action configureParser = null) @@ -40,7 +36,7 @@ private static void SetupRenderer( ConfigureTemplateContext = configureTemplateContext, ConfigureParser = configureParser }; - Email.DefaultRenderer = new LiquidRenderer(Options.Create(options)); + return new LiquidRenderer(Options.Create(options)); } [Fact] @@ -51,8 +47,9 @@ public void Model_With_List_Template_Matches() var email = Email .From(FromEmail) .To(ToEmail) - .Subject(Subject) - .UsingTemplate(template, new ViewModel { Name = "LUKE", Numbers = new[] { "1", "2", "3" } }); + .Subject(Subject); + email.Renderer = SetupRenderer(); + email.UsingTemplate(template, new ViewModel { Name = "LUKE", Numbers = ["1", "2", "3"] }); email.Data.Body.Should().Be("sup LUKE here is a list 123"); } @@ -60,10 +57,10 @@ public void Model_With_List_Template_Matches() [Fact] public void Custom_Context_Values() { - SetupRenderer(new NullFileProvider(), (context, model) => + var renderer = SetupRenderer(new NullFileProvider(), (context, _) => { context.SetValue("FirstName", "Samantha"); - context.SetValue("IntegerNumbers", new[] {3, 2, 1}); + context.SetValue("IntegerNumbers", (int[])[3, 2, 1]); }); const string template = "sup {{ FirstName }} here is a list {% for i in IntegerNumbers %}{{ i }}{% endfor %}"; @@ -71,8 +68,9 @@ public void Custom_Context_Values() var email = Email .From(FromEmail) .To(ToEmail) - .Subject(Subject) - .UsingTemplate(template, new ViewModel { Name = "LUKE", Numbers = new[] { "1", "2", "3" } }); + .Subject(Subject); + email.Renderer = renderer; + email.UsingTemplate(template, new ViewModel { Name = "LUKE", Numbers = ["1", "2", "3"] }); email.Data.Body.Should().Be("sup Samantha here is a list 321"); } @@ -89,16 +87,18 @@ public void Reuse_Cached_Templates() var email = Email .From(FromEmail) .To(ToEmail) - .Subject(Subject) - .UsingTemplate(template, new ViewModel { Name = i.ToString(), Numbers = new[] { "1", "2", "3" } }); + .Subject(Subject); + email.Renderer = SetupRenderer(); + email.UsingTemplate(template, new ViewModel { Name = i.ToString(), Numbers = ["1", "2", "3"] }); email.Data.Body.Should().Be("sup " + i + " here is a list 123"); var email2 = Email .From(FromEmail) .To(ToEmail) - .Subject(Subject) - .UsingTemplate(template2, new ViewModel { Name = i.ToString() }); + .Subject(Subject); + email2.Renderer = SetupRenderer(); + email2.UsingTemplate(template2, new ViewModel { Name = i.ToString() }); email2.Data.Body.Should().Be("sup " + i + " this is the second template"); } @@ -111,8 +111,9 @@ public void New_Model_Template_Matches() var email = new Email(FromEmail) .To(ToEmail) - .Subject(Subject) - .UsingTemplate(template, new ViewModel { Name = "LUKE" }); + .Subject(Subject); + email.Renderer = SetupRenderer(); + email.UsingTemplate(template, new ViewModel { Name = "LUKE" }); email.Data.Body.Should().Be("sup LUKE"); } @@ -124,8 +125,9 @@ public void New_Model_With_List_Template_Matches() var email = new Email(FromEmail) .To(ToEmail) - .Subject(Subject) - .UsingTemplate(template, new ViewModel { Name = "LUKE", Numbers = new[] { "1", "2", "3" } }); + .Subject(Subject); + email.Renderer = SetupRenderer(); + email.UsingTemplate(template, new ViewModel { Name = "LUKE", Numbers = ["1", "2", "3"] }); email.Data.Body.Should().Be("sup LUKE here is a list 123"); } @@ -141,15 +143,17 @@ public void New_Reuse_Cached_Templates() { var email = new Email(FromEmail) .To(ToEmail) - .Subject(Subject) - .UsingTemplate(template, new ViewModel { Name = i.ToString(), Numbers = new[] { "1", "2", "3" } }); + .Subject(Subject); + email.Renderer = SetupRenderer(); + email.UsingTemplate(template, new ViewModel { Name = i.ToString(), Numbers = ["1", "2", "3"] }); email.Data.Body.Should().Be("sup " + i + " here is a list 123"); var email2 = new Email(FromEmail) .To(ToEmail) - .Subject(Subject) - .UsingTemplate(template2, new ViewModel { Name = i.ToString() }); + .Subject(Subject); + email2.Renderer = SetupRenderer(); + email2.UsingTemplate(template2, new ViewModel { Name = i.ToString() }); email2.Data.Body.Should().Be("sup " + i + " this is the second template"); } @@ -158,15 +162,16 @@ public void New_Reuse_Cached_Templates() [Fact] public void Should_be_able_to_use_project_layout() { - SetupRenderer(new PhysicalFileProvider(Path.Combine(new FileInfo(Assembly.GetExecutingAssembly().Location).Directory!.FullName, "EmailTemplates"))); + var renderer = SetupRenderer(new PhysicalFileProvider(Path.Combine(new FileInfo(Assembly.GetExecutingAssembly().Location).Directory!.FullName, "EmailTemplates"))); const string template = @"{% layout '_layout.liquid' %} sup {{ Name }} here is a list {% for i in Numbers %}{{ i }}{% endfor %}"; var email = new Email(FromEmail) .To(ToEmail) - .Subject(Subject) - .UsingTemplate(template, new ViewModel{ Name = "LUKE", Numbers = new[] { "1", "2", "3" } }); + .Subject(Subject); + email.Renderer = renderer; + email.UsingTemplate(template, new ViewModel{ Name = "LUKE", Numbers = ["1", "2", "3"] }); email.Data.Body.Should().Be($"

Hello!

{Environment.NewLine}
{Environment.NewLine}sup LUKE here is a list 123
"); } @@ -174,15 +179,17 @@ public void Should_be_able_to_use_project_layout() [Fact] public void Should_be_able_to_use_embedded_layout() { - SetupRenderer(new EmbeddedFileProvider(typeof(LiquidTests).Assembly, "FluentEmail.Liquid.Tests.EmailTemplates")); + var renderer = SetupRenderer(new EmbeddedFileProvider(typeof(LiquidTests).Assembly, "FluentEmail.Liquid.Tests.EmailTemplates")); const string template = @"{% layout '_embedded.liquid' %} sup {{ Name }} here is a list {% for i in Numbers %}{{ i }}{% endfor %}"; var email = new Email(FromEmail) .To(ToEmail) - .Subject(Subject) - .UsingTemplate(template, new ViewModel{ Name = "LUKE", Numbers = new[] { "1", "2", "3" } }); + .Subject(Subject); + email.Renderer = renderer; + email + .UsingTemplate(template, new ViewModel{ Name = "LUKE", Numbers = ["1", "2", "3"] }); email.Data.Body.Should().Be($"

Hello!

{Environment.NewLine}
{Environment.NewLine}sup LUKE here is a list 123
"); } @@ -190,7 +197,7 @@ public void Should_be_able_to_use_embedded_layout() [Fact] public void Should_be_able_to_configure_parser() { - SetupRenderer( + var renderer = SetupRenderer( new EmbeddedFileProvider(typeof(LiquidTests).Assembly, "FluentEmail.Liquid.Tests.EmailTemplates"), configureParser: parser => parser.RegisterExpressionTag("testTag", TestTag) ); @@ -200,8 +207,9 @@ public void Should_be_able_to_configure_parser() var email = Email .From(FromEmail) .To(ToEmail) - .Subject(Subject) - .UsingTemplate(template, new ViewModel { Name = "LUKE" }); + .Subject(Subject); + email.Renderer = renderer; + email.UsingTemplate(template, new ViewModel { Name = "LUKE" }); email.Data.Body.Should().Be("sup LUKE here is a custom tag: Hello from custom tag test"); @@ -213,6 +221,7 @@ static async ValueTask TestTag(Expression pathExpression, TextWriter } } + [SuppressMessage("ReSharper", "UnusedAutoPropertyAccessor.Local")] private class ViewModel { public string Name { get; set; } diff --git a/test/FluentEmail.Razor.Tests/FluentEmail.Razor.Tests.csproj b/test/FluentEmail.Razor.Tests/FluentEmail.Razor.Tests.csproj index c6f2827..f79ab92 100644 --- a/test/FluentEmail.Razor.Tests/FluentEmail.Razor.Tests.csproj +++ b/test/FluentEmail.Razor.Tests/FluentEmail.Razor.Tests.csproj @@ -1,7 +1,6 @@  - net8.0 true @@ -27,8 +26,4 @@ - - - - diff --git a/test/FluentEmail.Razor.Tests/RazorTests.cs b/test/FluentEmail.Razor.Tests/RazorTests.cs index a247fa6..3ae2240 100644 --- a/test/FluentEmail.Razor.Tests/RazorTests.cs +++ b/test/FluentEmail.Razor.Tests/RazorTests.cs @@ -9,22 +9,22 @@ namespace FluentEmail.Razor.Tests { public class RazorTests { - const string toEmail = "bob@test.com"; - const string fromEmail = "johno@test.com"; - const string subject = "sup dawg"; + private const string ToEmail = "bob@test.com"; + private const string FromEmail = "johno@test.com"; + private const string Subject = "sup dawg"; [Fact] public void Anonymous_Model_With_List_Template_Matches() { - string template = "sup @Model.Name here is a list @foreach(var i in Model.Numbers) { @i }"; + var template = "sup @Model.Name here is a list @foreach(var i in Model.Numbers) { @i }"; - var email = new Email(fromEmail) + var email = new Email(FromEmail) { Renderer = new RazorRenderer() } - .To(toEmail) - .Subject(subject) - .UsingTemplate(template, new { Name = "LUKE", Numbers = new string[] { "1", "2", "3" } }); + .To(ToEmail) + .Subject(Subject) + .UsingTemplate(template, new { Name = "LUKE", Numbers = (string[])["1", "2", "3"] }); email.Data.Body.Should().Be("sup LUKE here is a list 123"); } @@ -32,27 +32,27 @@ public void Anonymous_Model_With_List_Template_Matches() [Fact] public void Reuse_Cached_Templates() { - string template = "sup @Model.Name here is a list @foreach(var i in Model.Numbers) { @i }"; - string template2 = "sup @Model.Name this is the second template"; + var template = "sup @Model.Name here is a list @foreach(var i in Model.Numbers) { @i }"; + var template2 = "sup @Model.Name this is the second template"; for (var i = 0; i < 10; i++) { - var email = new Email(fromEmail) + var email = new Email(FromEmail) { Renderer = new RazorRenderer() } - .To(toEmail) - .Subject(subject) - .UsingTemplate(template, new { Name = i, Numbers = new string[] { "1", "2", "3" } }); + .To(ToEmail) + .Subject(Subject) + .UsingTemplate(template, new { Name = i, Numbers = (string[])["1", "2", "3"] }); email.Data.Body.Should().Be("sup " + i + " here is a list 123"); - var email2 = new Email(fromEmail) + var email2 = new Email(FromEmail) { Renderer = new RazorRenderer() } - .To(toEmail) - .Subject(subject) + .To(ToEmail) + .Subject(Subject) .UsingTemplate(template2, new { Name = i }); email2.Data.Body.Should().Be("sup " + i + " this is the second template"); @@ -62,14 +62,14 @@ public void Reuse_Cached_Templates() [Fact] public void New_Anonymous_Model_Template_Matches() { - string template = "sup @Model.Name"; + var template = "sup @Model.Name"; - var email = new Email(fromEmail) + var email = new Email(FromEmail) { Renderer = new RazorRenderer() } - .To(toEmail) - .Subject(subject) + .To(ToEmail) + .Subject(Subject) .UsingTemplate(template, new { Name = "LUKE" }); email.Data.Body.Should().Be("sup LUKE"); @@ -78,15 +78,15 @@ public void New_Anonymous_Model_Template_Matches() [Fact] public void New_Anonymous_Model_With_List_Template_Matches() { - string template = "sup @Model.Name here is a list @foreach(var i in Model.Numbers) { @i }"; + var template = "sup @Model.Name here is a list @foreach(var i in Model.Numbers) { @i }"; - var email = new Email(fromEmail) + var email = new Email(FromEmail) { Renderer = new RazorRenderer() } - .To(toEmail) - .Subject(subject) - .UsingTemplate(template, new { Name = "LUKE", Numbers = new string[] { "1", "2", "3" } }); + .To(ToEmail) + .Subject(Subject) + .UsingTemplate(template, new { Name = "LUKE", Numbers = (string[])["1", "2", "3"] }); email.Data.Body.Should().Be("sup LUKE here is a list 123"); } @@ -94,27 +94,27 @@ public void New_Anonymous_Model_With_List_Template_Matches() [Fact] public void New_Reuse_Cached_Templates() { - string template = "sup @Model.Name here is a list @foreach(var i in Model.Numbers) { @i }"; - string template2 = "sup @Model.Name this is the second template"; + var template = "sup @Model.Name here is a list @foreach(var i in Model.Numbers) { @i }"; + var template2 = "sup @Model.Name this is the second template"; for (var i = 0; i < 10; i++) { - var email = new Email(fromEmail) + var email = new Email(FromEmail) { Renderer = new RazorRenderer() } - .To(toEmail) - .Subject(subject) - .UsingTemplate(template, new { Name = i, Numbers = new string[] { "1", "2", "3" } }); + .To(ToEmail) + .Subject(Subject) + .UsingTemplate(template, new { Name = i, Numbers = (string[])["1", "2", "3"] }); email.Data.Body.Should().Be("sup " + i + " here is a list 123"); - var email2 = new Email(fromEmail) + var email2 = new Email(FromEmail) { Renderer = new RazorRenderer() } - .To(toEmail) - .Subject(subject) + .To(ToEmail) + .Subject(Subject) .UsingTemplate(template2, new { Name = i }); email2.Data.Body.Should().Be("sup " + i + " this is the second template"); @@ -123,12 +123,12 @@ public void New_Reuse_Cached_Templates() [Fact] - public void Should_be_able_to_use_project_layout_with_viewbag() + public void Should_be_able_to_use_project_layout_with_viewBag() { var projectRoot = Directory.GetCurrentDirectory(); Email.DefaultRenderer = new RazorRenderer(projectRoot); - string template = @" + var template = @" @{ Layout = ""./Shared/_Layout.cshtml""; } @@ -136,21 +136,21 @@ public void Should_be_able_to_use_project_layout_with_viewbag() dynamic viewBag = new ExpandoObject(); viewBag.Title = "Hello!"; - var email = new Email(fromEmail) + var email = new Email(FromEmail) { Renderer = new RazorRenderer() } - .To(toEmail) - .Subject(subject) - .UsingTemplate(template, new ViewModelWithViewBag{ Name = "LUKE", Numbers = new[] { "1", "2", "3" }, ViewBag = viewBag}); + .To(ToEmail) + .Subject(Subject) + .UsingTemplate(template, new ViewModelWithViewBag{ Name = "LUKE", Numbers = ["1", "2", "3"], ViewBag = viewBag}); email.Data.Body.Should().Be($"

Hello!

{Environment.NewLine}
{Environment.NewLine}sup LUKE here is a list 123
"); } [Fact] - public void Should_be_able_to_use_embedded_layout_with_viewbag() + public void Should_be_able_to_use_embedded_layout_with_viewBag() { - string template = @" + var template = @" @{ Layout = ""_EmbeddedLayout.cshtml""; } @@ -158,13 +158,13 @@ public void Should_be_able_to_use_embedded_layout_with_viewbag() dynamic viewBag = new ExpandoObject(); viewBag.Title = "Hello!"; - var email = new Email(fromEmail) + var email = new Email(FromEmail) { Renderer = new RazorRenderer(typeof(RazorTests)) } - .To(toEmail) - .Subject(subject) - .UsingTemplate(template, new ViewModelWithViewBag{ Name = "LUKE", Numbers = new[] { "1", "2", "3" }, ViewBag = viewBag}); + .To(ToEmail) + .Subject(Subject) + .UsingTemplate(template, new ViewModelWithViewBag{ Name = "LUKE", Numbers = ["1", "2", "3"], ViewBag = viewBag}); email.Data.Body.Should().Be($"

Hello!

{Environment.NewLine}
{Environment.NewLine}sup LUKE here is a list 123
"); }