Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update for Async Support & .NET 8 #54

Merged
merged 5 commits into from
May 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<IsPackable>false</IsPackable>
<RootNamespace>ICG.NetCore.Utilities.Email.Smtp.Tests</RootNamespace>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.0">
<PackageReference Include="coverlet.collector" Version="6.0.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="6.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
<PackageReference Include="Moq" Version="4.20.69" />
<PackageReference Include="xunit" Version="2.5.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.0">
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="8.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0" />
<PackageReference Include="Moq" Version="4.20.70" />
<PackageReference Include="xunit" Version="2.8.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
Expand Down
67 changes: 34 additions & 33 deletions src/NetCore.Utilities.Email.Smtp.Tests/SmtpServiceTests.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.Options;
using MimeKit;
using Moq;
Expand Down Expand Up @@ -60,7 +61,7 @@ public void AdminEmail_ShouldReturnNullWhenNoConfiguration()
}

[Fact]
public void SendToAdministrator_ShouldSend_DefaultingFromAndToAddress()
public async Task SendToAdministratorAsync_ShouldSend_DefaultingFromAndToAddress()
{
//Arrange
var subject = "Test";
Expand All @@ -71,15 +72,15 @@ public void SendToAdministrator_ShouldSend_DefaultingFromAndToAddress()
.Returns(mimeMessage).Verifiable();

//Act
_service.SendMessageToAdministrator(subject, message);
await _service.SendMessageToAdministratorAsync(subject, message);

//Verify
_mimeMessageFactoryMock.Verify();
_mimeKitServiceMock.Verify(k => k.SendEmail(mimeMessage));
_mimeKitServiceMock.Verify(k => k.SendEmailAsync(mimeMessage));
}

[Fact]
public void SendToAdministrator_ShouldSend_DefaultingFromAndToAddress_WithCCRecipients()
public async Task SendToAdministrator_ShouldSend_DefaultingFromAndToAddress_WithCCRecipients()
{
//Arrange
var subject = "Test";
Expand All @@ -91,15 +92,15 @@ public void SendToAdministrator_ShouldSend_DefaultingFromAndToAddress_WithCCReci
.Returns(mimeMessage).Verifiable();

//Act
_service.SendMessageToAdministrator(cc, subject, message);
await _service.SendMessageToAdministratorAsync(cc, subject, message);

//Verify
_mimeMessageFactoryMock.Verify();
_mimeKitServiceMock.Verify(k => k.SendEmail(mimeMessage));
_mimeKitServiceMock.Verify(k => k.SendEmailAsync(mimeMessage));
}

[Fact]
public void SendMessage_WithoutCCRecipients_ShouldSend_DefaultingFromAddress()
public async Task SendMessage_WithoutCCRecipients_ShouldSend_DefaultingFromAddress()
{
//Arrange
var to = "[email protected]";
Expand All @@ -111,15 +112,15 @@ public void SendMessage_WithoutCCRecipients_ShouldSend_DefaultingFromAddress()
.Returns(mimeMessage).Verifiable();

//Act
_service.SendMessage(to, subject, message);
await _service.SendMessageAsync(to, subject, message);

//Verify
_mimeMessageFactoryMock.Verify();
_mimeKitServiceMock.Verify(k => k.SendEmail(mimeMessage));
_mimeKitServiceMock.Verify(k => k.SendEmailAsync(mimeMessage));
}

[Fact]
public void SendMessageWithReplyTo_WithoutCCRecipients_ShouldSend_DefaultingFromAddress()
public async Task SendMessageWithReplyTo_WithoutCCRecipients_ShouldSend_DefaultingFromAddress()
{
//Arrange
var replyTo = "[email protected]";
Expand All @@ -133,18 +134,18 @@ public void SendMessageWithReplyTo_WithoutCCRecipients_ShouldSend_DefaultingFrom
.Returns(mimeMessage).Verifiable();

//Act
_service.SendWithReplyTo(replyTo, replyToName, to, subject, message);
await _service.SendWithReplyToAsync(replyTo, replyToName, to, subject, message);

//Verify
Assert.Equal(1, mimeMessage.ReplyTo.Count);
Assert.Single(mimeMessage.ReplyTo);
var replyToAsAdded = mimeMessage.ReplyTo.First();
Assert.Equal("\"Bob\" <[email protected]>", replyToAsAdded.ToString());
_mimeMessageFactoryMock.Verify();
_mimeKitServiceMock.Verify(k => k.SendEmail(mimeMessage));
_mimeKitServiceMock.Verify(k => k.SendEmailAsync(mimeMessage));
}

[Fact]
public void SendMessage_WithCCRecipients_ShouldSend_DefaultingFromAddress()
public async Task SendMessage_WithCCRecipients_ShouldSend_DefaultingFromAddress()
{
//Arrange
var to = "[email protected]";
Expand All @@ -157,15 +158,15 @@ public void SendMessage_WithCCRecipients_ShouldSend_DefaultingFromAddress()
.Returns(mimeMessage).Verifiable();

//Act
_service.SendMessage(to, cc, subject, message);
await _service.SendMessageAsync(to, cc, subject, message);

//Verify
_mimeMessageFactoryMock.Verify();
_mimeKitServiceMock.Verify(k => k.SendEmail(mimeMessage));
_mimeKitServiceMock.Verify(k => k.SendEmailAsync(mimeMessage));
}

[Fact]
public void SendMessageWithReplyTo_WithCCRecipients_ShouldSend_DefaultingFromAddress()
public async Task SendMessageWithReplyTo_WithCCRecipients_ShouldSend_DefaultingFromAddress()
{
//Arrange
var replyTo = "[email protected]";
Expand All @@ -180,18 +181,18 @@ public void SendMessageWithReplyTo_WithCCRecipients_ShouldSend_DefaultingFromAdd
.Returns(mimeMessage).Verifiable();

//Act
_service.SendWithReplyTo(replyTo, replyToName, to, cc, subject, message);
await _service.SendWithReplyToAsync(replyTo, replyToName, to, cc, subject, message);

//Verify
Assert.Equal(1, mimeMessage.ReplyTo.Count);
Assert.Single(mimeMessage.ReplyTo);
var replyToAsAdded = mimeMessage.ReplyTo.First();
Assert.Equal("\"Bob\" <[email protected]>", replyToAsAdded.ToString());
_mimeMessageFactoryMock.Verify();
_mimeKitServiceMock.Verify(k => k.SendEmail(mimeMessage));
_mimeKitServiceMock.Verify(k => k.SendEmailAsync(mimeMessage));
}

[Fact]
public void SendMessageWithAttachment_ShouldSend_DefaultingFromAddress()
public async Task SendMessageWithAttachment_ShouldSend_DefaultingFromAddress()
{
//Arrange
var to = "[email protected]";
Expand All @@ -206,15 +207,15 @@ public void SendMessageWithAttachment_ShouldSend_DefaultingFromAddress()
.Returns(mimeMessage).Verifiable();

//Act
_service.SendMessageWithAttachment(to, cc, subject, fileContent, fileName, message, null);
await _service.SendMessageWithAttachmentAsync(to, cc, subject, fileContent, fileName, message, null);

//Assets
_mimeMessageFactoryMock.Verify();
_mimeKitServiceMock.Verify(k => k.SendEmail(mimeMessage));
_mimeKitServiceMock.Verify(k => k.SendEmailAsync(mimeMessage));
}

[Fact]
public void SendMessage_ShouldPassOptionalTemplateName_ToMessageMethods()
public async Task SendMessage_ShouldPassOptionalTemplateName_ToMessageMethods()
{
//Arrange
var to = "[email protected]";
Expand All @@ -228,15 +229,15 @@ public void SendMessage_ShouldPassOptionalTemplateName_ToMessageMethods()
.Returns(mimeMessage).Verifiable();

//Act
_service.SendMessage(to, cc, subject, message, null, requestedTemplate);
await _service.SendMessageAsync(to, cc, subject, message, null, requestedTemplate);

//Assets
_mimeMessageFactoryMock.Verify();
_mimeKitServiceMock.Verify(k => k.SendEmail(mimeMessage));
_mimeKitServiceMock.Verify(k => k.SendEmailAsync(mimeMessage));
}

[Fact]
public void SendMessageWithReplyTo_ShouldPassOptionalTemplateName_ToMessageMethods()
public async Task SendMessageWithReplyTo_ShouldPassOptionalTemplateName_ToMessageMethods()
{
//Arrange
var replyTo = "[email protected]";
Expand All @@ -252,18 +253,18 @@ public void SendMessageWithReplyTo_ShouldPassOptionalTemplateName_ToMessageMetho
.Returns(mimeMessage).Verifiable();

//Act
_service.SendWithReplyTo(replyTo, replyToName, to, cc, subject, message, null, requestedTemplate);
await _service.SendWithReplyToAsync(replyTo, replyToName, to, cc, subject, message, null, requestedTemplate);

//Assets
Assert.Equal(1, mimeMessage.ReplyTo.Count);
Assert.Single(mimeMessage.ReplyTo);
var replyToAsAdded = mimeMessage.ReplyTo.First();
Assert.Equal("\"Bob\" <[email protected]>", replyToAsAdded.ToString());
_mimeMessageFactoryMock.Verify();
_mimeKitServiceMock.Verify(k => k.SendEmail(mimeMessage));
_mimeKitServiceMock.Verify(k => k.SendEmailAsync(mimeMessage));
}

[Fact]
public void SendMessageWithAttachment_ShouldPassOptionalTemplateName_ToMessageMethods()
public async Task SendMessageWithAttachment_ShouldPassOptionalTemplateName_ToMessageMethods()
{
//Arrange
var to = "[email protected]";
Expand All @@ -279,11 +280,11 @@ public void SendMessageWithAttachment_ShouldPassOptionalTemplateName_ToMessageMe
.Returns(mimeMessage).Verifiable();

//Act
_service.SendMessageWithAttachment(to, cc, subject, fileContent, fileName, message, null, requestedTemplate);
await _service.SendMessageWithAttachmentAsync(to, cc, subject, fileContent, fileName, message, null, requestedTemplate);

//Assets
_mimeMessageFactoryMock.Verify();
_mimeKitServiceMock.Verify(k => k.SendEmail(mimeMessage));
_mimeKitServiceMock.Verify(k => k.SendEmailAsync(mimeMessage));
}
}
}
11 changes: 6 additions & 5 deletions src/NetCore.Utilities.Email.Smtp/MimeKitService.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Diagnostics.CodeAnalysis;
using System.Threading.Tasks;
using MailKit.Net.Smtp;
using Microsoft.Extensions.Options;
using MimeKit;
Expand All @@ -14,7 +15,7 @@ public interface IMimeKitService
/// Sends an email message
/// </summary>
/// <param name="toSend">The message to send</param>
void SendEmail(MimeMessage toSend);
Task SendEmailAsync(MimeMessage toSend);
}

/// <summary>
Expand All @@ -38,13 +39,13 @@ public MimeKitService(IOptions<SmtpServiceOptions> configuration)
}

/// <inheritdoc />
public void SendEmail(MimeMessage toSend)
public async Task SendEmailAsync(MimeMessage toSend)
{
using var client = new SmtpClient();
client.Connect(_configuration.Value.Server, _configuration.Value.Port, _configuration.Value.UseSsl);
await client.ConnectAsync(_configuration.Value.Server, _configuration.Value.Port, _configuration.Value.UseSsl);
client.AuthenticationMechanisms.Remove("XOAUTH2");
client.Authenticate(_configuration.Value.SenderUsername, _configuration.Value.SenderPassword);
client.Send(toSend);
await client.AuthenticateAsync(_configuration.Value.SenderUsername, _configuration.Value.SenderPassword);
await client.SendAsync(toSend);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<RootNamespace>ICG.NetCore.Utilities.Email.Smtp</RootNamespace>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
Expand All @@ -10,8 +10,8 @@
<PropertyGroup>
<PackageId>ICG.NetCore.Utilities.Email.Smtp</PackageId>
<Title>NetCore Utilities Email SMTP</Title>
<Description>A library providing an easy to use set of functions rounding the SMTPClient.</Description>
<Copyright>Copyright 2021, IowaComputerGurus, Inc. All Rights Reserved</Copyright>
<Description>A library providing easy access to sending emails, including templated emails, via SMTP from .NET 8+.</Description>
<Copyright>Copyright 2024, IowaComputerGurus, Inc. All Rights Reserved</Copyright>
<PackageProjectUrl>https://github.com/IowaComputerGurus/netcore.utilities.email.smtp</PackageProjectUrl>
<PackageTags>aspnetcore;utility;email</PackageTags>
<RepositoryUrl>https://github.com/IowaComputerGurus/netcore.utilities.email.smtp</RepositoryUrl>
Expand All @@ -33,14 +33,14 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="icg.netcore.utilities.email" Version="6.2.0" />
<PackageReference Include="MailKit" Version="2.15.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Options" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="6.0.0" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1">
<PackageReference Include="icg.netcore.utilities.email" Version="7.0.0" />
<PackageReference Include="MailKit" Version="4.6.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Options" Version="8.0.2" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="8.0.0" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
Expand Down
Loading
Loading