Skip to content

Commit 8ebf02b

Browse files
Initial working version
1 parent c42239c commit 8ebf02b

File tree

6 files changed

+122
-29
lines changed

6 files changed

+122
-29
lines changed

src/NetCore.Utilities.Email.SendGrid.Tests/SmtpServiceTests.cs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,16 @@ public class SendGridServiceTests
1616
AlwaysTemplateEmails = false
1717
};
1818

19-
private Mock<ISendGridMessageBuilder> _sendGridMessageBuilderMock;
19+
private readonly Mock<ISendGridMessageBuilder> _sendGridMessageBuilderMock;
20+
private readonly Mock<ISendGridSender> _sendGridSenderMock;
2021
private readonly ISendGridService _service;
2122

22-
public SendGridServiceTests(Mock<ISendGridMessageBuilder> sendGridMessageBuilderMock)
23+
public SendGridServiceTests()
2324
{
24-
_sendGridMessageBuilderMock = sendGridMessageBuilderMock;
25+
_sendGridMessageBuilderMock = new Mock<ISendGridMessageBuilder>();
26+
_sendGridSenderMock = new Mock<ISendGridSender>();
2527
_service = new SendGridService(new OptionsWrapper<SendGridServiceOptions>(_options),
26-
sendGridMessageBuilderMock.Object);
28+
_sendGridMessageBuilderMock.Object, _sendGridSenderMock.Object);
2729
}
2830

2931
[Fact]
@@ -43,7 +45,7 @@ public void AdminEmail_ShouldReturnConfigurationEmail()
4345
public void AdminEmail_ShouldReturnNullWhenNoConfiguration()
4446
{
4547
//Arrange
46-
var testService = new SendGridService(new OptionsWrapper<SendGridServiceOptions>(null), _sendGridMessageBuilderMock.Object);
48+
var testService = new SendGridService(new OptionsWrapper<SendGridServiceOptions>(null), _sendGridMessageBuilderMock.Object, _sendGridSenderMock.Object);
4749

4850
//Act
4951
var result = testService.AdminEmail;

src/NetCore.Utilities.Email.SendGrid.Tests/StartupExtensiosTests.cs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using Microsoft.AspNetCore.Hosting;
22
using Microsoft.Extensions.Configuration;
33
using Microsoft.Extensions.DependencyInjection;
4+
using Microsoft.Extensions.Logging;
45
using Microsoft.Extensions.Options;
56
using Moq;
67
using Xunit;
@@ -48,6 +49,7 @@ public void ServiceCollection_ShouldRegisterSendGridService()
4849
collection.AddSingleton(new Mock<Microsoft.Extensions.Hosting.IHostingEnvironment>().Object);
4950
collection.AddSingleton(new Mock<IHostingEnvironment>().Object);
5051
collection.UseIcgNetCoreUtilitiesEmailSendGrid(configuration);
52+
collection.AddLogging();
5153
var services = collection.BuildServiceProvider();
5254

5355
//Act
@@ -57,5 +59,49 @@ public void ServiceCollection_ShouldRegisterSendGridService()
5759
Assert.NotNull(result);
5860
Assert.IsType<SendGridService>(result);
5961
}
62+
63+
64+
[Fact]
65+
public void ServiceCollection_ShouldRegisterSendMessageBuilder()
66+
{
67+
//Arrange
68+
var collection = new ServiceCollection();
69+
var configuration = new ConfigurationBuilder()
70+
.AddJsonFile("appsettings.json")
71+
.Build();
72+
collection.AddSingleton(new Mock<Microsoft.Extensions.Hosting.IHostingEnvironment>().Object);
73+
collection.AddSingleton(new Mock<IHostingEnvironment>().Object);
74+
collection.AddLogging();
75+
collection.UseIcgNetCoreUtilitiesEmailSendGrid(configuration);
76+
var services = collection.BuildServiceProvider();
77+
78+
//Act
79+
var result = services.GetService<ISendGridMessageBuilder>();
80+
81+
//Assert
82+
Assert.NotNull(result);
83+
Assert.IsType<SendGridMessageBuilder>(result);
84+
}
85+
86+
[Fact]
87+
public void ServiceCollection_ShouldRegisterSendGridSender()
88+
{
89+
//Arrange
90+
var collection = new ServiceCollection();
91+
var configuration = new ConfigurationBuilder()
92+
.AddJsonFile("appsettings.json")
93+
.Build();
94+
collection.AddSingleton(new Mock<Microsoft.Extensions.Hosting.IHostingEnvironment>().Object);
95+
collection.AddSingleton(new Mock<IHostingEnvironment>().Object);
96+
collection.UseIcgNetCoreUtilitiesEmailSendGrid(configuration);
97+
var services = collection.BuildServiceProvider();
98+
99+
//Act
100+
var result = services.GetService<ISendGridSender>();
101+
102+
//Assert
103+
Assert.NotNull(result);
104+
Assert.IsType<SendGridSender>(result);
105+
}
60106
}
61107
}

src/NetCore.Utilities.Email.SendGrid/DependencyResolution/StartupExtensions.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ public static void UseIcgNetCoreUtilitiesEmailSendGrid(this IServiceCollection s
2121
//Bind additional services
2222
services.AddTransient<ISendGridService, SendGridService>();
2323
services.AddTransient<ISendGridMessageBuilder, SendGridMessageBuilder>();
24+
services.AddTransient<ISendGridSender, SendGridSender>();
2425
services.Configure<SendGridServiceOptions>(configuration.GetSection(nameof(SendGridServiceOptions)));
2526
}
2627
}

src/NetCore.Utilities.Email.SendGrid/SendGridMessageBuilder.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,12 @@ public class SendGridMessageBuilder : ISendGridMessageBuilder
6767
/// <param name="options"></param>
6868
/// <param name="loggerFactory"></param>
6969
public SendGridMessageBuilder(IHostingEnvironment hostingEnvironment, IEmailTemplateFactory emailTemplateFactory,
70-
IOptions<SendGridServiceOptions> options, ILoggerFactory loggerFactory)
70+
IOptions<SendGridServiceOptions> options, ILogger<SendGridMessageBuilder> logger)
7171
{
7272
_hostingEnvironment = hostingEnvironment;
7373
_emailTemplateFactory = emailTemplateFactory;
7474
_serviceOptions = options.Value;
75-
_logger = loggerFactory.CreateLogger<SendGridMessageBuilder>();
75+
_logger = logger;
7676
}
7777

7878
/// <inheritdoc />
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
using System.Threading.Tasks;
2+
using SendGrid;
3+
using SendGrid.Helpers.Mail;
4+
5+
namespace ICG.NetCore.Utilities.Email.SendGrid
6+
{
7+
/// <summary>
8+
/// Internal service to abstract the actual SendGrid implementation to allow for proper unit testing of the remainder
9+
/// of the project. Not intended for external usage
10+
/// </summary>
11+
public interface ISendGridSender
12+
{
13+
/// <summary>
14+
/// Sends a mail message using the provided API key
15+
/// </summary>
16+
/// <param name="apiKey"></param>
17+
/// <param name="message"></param>
18+
/// <returns></returns>
19+
Task<bool> SendMessage(string apiKey, SendGridMessage message);
20+
}
21+
22+
/// <inheritdoc />
23+
public class SendGridSender : ISendGridSender
24+
{
25+
/// <inheritdoc />
26+
public async Task<bool> SendMessage(string apiKey, SendGridMessage message)
27+
{
28+
var client = new SendGridClient(apiKey);
29+
var result = await client.SendEmailAsync(message);
30+
return result.IsSuccessStatusCode;
31+
}
32+
}
33+
}

src/NetCore.Utilities.Email.SendGrid/SendGridService.cs

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -22,23 +22,23 @@ public interface ISendGridService
2222
/// </summary>
2323
/// <param name="subject">The message subject</param>
2424
/// <param name="bodyHtml">The message body</param>
25-
void SendMessageToAdministrator(string subject, string bodyHtml);
25+
bool SendMessageToAdministrator(string subject, string bodyHtml);
2626

2727
/// <summary>
2828
/// Sends a message to the administrator as well as the additional contacts provided.
2929
/// </summary>
3030
/// <param name="ccAddressList">Additional email addresses to add to the CC line</param>
3131
/// <param name="subject">The email subject</param>
3232
/// <param name="bodyHtml">The HTML content of the email</param>
33-
void SendMessageToAdministrator(IEnumerable<string> ccAddressList, string subject, string bodyHtml);
33+
bool SendMessageToAdministrator(IEnumerable<string> ccAddressList, string subject, string bodyHtml);
3434

3535
/// <summary>
3636
/// Sends a message to the specified recipient, with the supplied subject and body
3737
/// </summary>
3838
/// <param name="toAddress">Who is receiving the email</param>
3939
/// <param name="subject">The message subject</param>
4040
/// <param name="bodyHtml">The message body</param>
41-
void SendMessage(string toAddress, string subject, string bodyHtml);
41+
bool SendMessage(string toAddress, string subject, string bodyHtml);
4242

4343
/// <summary>
4444
/// Sends a message to the specified recipient, and CC's with the supplied subject and body
@@ -48,8 +48,8 @@ public interface ISendGridService
4848
/// <param name="subject">The message subject</param>
4949
/// <param name="bodyHtml">The message body</param>
5050
/// <param name="templateName">The optional custom template to override with</param>
51-
/// <param name="customKey">The custom key for API usage if needed</param>
52-
void SendMessage(string toAddress, IEnumerable<string> ccAddressList, string subject, string bodyHtml, string templateName = "", string customKey = "");
51+
/// <param name="senderKeyName">The custom key for API usage if needed</param>
52+
bool SendMessage(string toAddress, IEnumerable<string> ccAddressList, string subject, string bodyHtml, string templateName = "", string senderKeyName = "");
5353

5454
/// <summary>
5555
/// Creates a message with an attachment
@@ -61,17 +61,18 @@ public interface ISendGridService
6161
/// <param name="fileName">Attachment file name</param>
6262
/// <param name="bodyHtml">The HTML body contents</param>
6363
/// <param name="templateName">The optional custom template to override with</param>
64-
/// <param name="customKey">The custom key for API usage if needed</param>
64+
/// <param name="senderKeyName">The custom key for API usage if needed</param>
6565
/// <returns></returns>
66-
void SendMessageWithAttachment(string toAddress, IEnumerable<string> ccAddressList, string subject,
67-
byte[] fileContent, string fileName, string bodyHtml, string templateName = "", string customKey = "");
66+
bool SendMessageWithAttachment(string toAddress, IEnumerable<string> ccAddressList, string subject,
67+
byte[] fileContent, string fileName, string bodyHtml, string templateName = "", string senderKeyName = "");
6868
}
6969

7070
/// <inheritdoc />
7171
public class SendGridService : ISendGridService
7272
{
7373
private readonly SendGridServiceOptions _serviceOptions;
7474
private readonly ISendGridMessageBuilder _messageBuilder;
75+
private readonly ISendGridSender _sender;
7576

7677
/// <inheritdoc />
7778
public string AdminEmail => _serviceOptions?.AdminEmail;
@@ -80,54 +81,64 @@ public class SendGridService : ISendGridService
8081
/// DI Capable Constructor for SendGrid message delivery using MimeKit/MailKit
8182
/// </summary>
8283
/// <param name="serviceOptions"></param>
83-
public SendGridService(IOptions<SendGridServiceOptions> serviceOptions, ISendGridMessageBuilder messageBuilder)
84+
/// <param name="messageBuilder"></param>
85+
public SendGridService(IOptions<SendGridServiceOptions> serviceOptions, ISendGridMessageBuilder messageBuilder, ISendGridSender sender)
8486
{
8587
_messageBuilder = messageBuilder;
88+
_sender = sender;
8689
_serviceOptions = serviceOptions.Value;
8790
}
8891

8992
/// <inheritdoc />
90-
public void SendMessageToAdministrator(string subject, string bodyHtml)
93+
public bool SendMessageToAdministrator(string subject, string bodyHtml)
9194
{
9295
//Force to address
93-
SendMessage(_serviceOptions.AdminEmail, null, subject, bodyHtml);
96+
return SendMessage(_serviceOptions.AdminEmail, null, subject, bodyHtml);
9497
}
9598

9699
/// <inheritdoc />
97-
public void SendMessageToAdministrator(IEnumerable<string> ccAddressList, string subject, string bodyHtml)
100+
public bool SendMessageToAdministrator(IEnumerable<string> ccAddressList, string subject, string bodyHtml)
98101
{
99-
SendMessage(_serviceOptions.AdminEmail, ccAddressList, subject, bodyHtml);
102+
return SendMessage(_serviceOptions.AdminEmail, ccAddressList, subject, bodyHtml);
100103
}
101104

102105
/// <inheritdoc />
103-
public void SendMessage(string toAddress, string subject, string bodyHtml)
106+
public bool SendMessage(string toAddress, string subject, string bodyHtml)
104107
{
105108
//Call full overload
106-
SendMessage(toAddress, null, subject, bodyHtml);
109+
return SendMessage(toAddress, null, subject, bodyHtml);
107110
}
108111

109112
/// <inheritdoc />
110-
public void SendMessage(string toAddress, IEnumerable<string> ccAddressList, string subject, string bodyHtml, string templateName = "", string customKey = "")
113+
public bool SendMessage(string toAddress, IEnumerable<string> ccAddressList, string subject, string bodyHtml, string templateName = "", string senderKeyName = "")
111114
{
112115
//Get the message to send
113116
var toSend = _messageBuilder.CreateMessage(_serviceOptions.AdminEmail, toAddress, ccAddressList, subject,
114117
bodyHtml, templateName);
115118

116-
119+
//Determine the key to use
120+
var apiKey = _serviceOptions.SendGridApiKey;
121+
if (!string.IsNullOrEmpty(senderKeyName))
122+
apiKey = _serviceOptions.AdditionalApiKeys[senderKeyName];
117123

118-
////Send
119-
//_mimeKitService.SendEmail(toSend);
124+
//Send
125+
return _sender.SendMessage(apiKey, toSend).GetAwaiter().GetResult();
120126
}
121127

122128
/// <inheritdoc />
123-
public void SendMessageWithAttachment(string toAddress, IEnumerable<string> ccAddressList, string subject, byte[] fileContent, string fileName, string bodyHtml, string templateName = "", string customKey = "")
129+
public bool SendMessageWithAttachment(string toAddress, IEnumerable<string> ccAddressList, string subject, byte[] fileContent, string fileName, string bodyHtml, string templateName = "", string senderKeyName = "")
124130
{
125131
//Get the message to send
126132
var toSend = _messageBuilder.CreateMessageWithAttachment(_serviceOptions.AdminEmail, toAddress,
127133
ccAddressList, fileContent, fileName, subject, bodyHtml, templateName);
128134

129-
////Send
130-
//_mimeKitService.SendEmail(toSend);
135+
//Determine the key to use
136+
var apiKey = _serviceOptions.SendGridApiKey;
137+
if (!string.IsNullOrEmpty(senderKeyName))
138+
apiKey = _serviceOptions.AdditionalApiKeys[senderKeyName];
139+
140+
//Send
141+
return _sender.SendMessage(apiKey, toSend).GetAwaiter().GetResult();
131142
}
132143
}
133144
}

0 commit comments

Comments
 (0)