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

#336 Implementation of core logic for placing an sms notification order #380

Merged
merged 24 commits into from
Jan 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
7f2b28b
SMS notification channel added in the ENUM
khanrn Jan 16, 2024
1d95637
SMS template added in NotificationTemplate
khanrn Jan 16, 2024
3d907e6
SMS template added in NotificationTemplate 2
khanrn Jan 16, 2024
81868e5
Added JSON subtype for SMS in the notification interface
khanrn Jan 16, 2024
abbda3d
Renamed class and interface for OrderRequestService
khanrn Jan 16, 2024
b03780b
Renamed RegisterNotificationorder method
khanrn Jan 16, 2024
60680ea
Default email from address property name fixed
khanrn Jan 16, 2024
5a6d095
Added default sender number in the config
khanrn Jan 16, 2024
963c250
Extended method for setting default value when empty
khanrn Jan 16, 2024
e4233b5
Fixed the prop name for the default SMS sender
khanrn Jan 16, 2024
ccccb08
Shortened sender setting method name
khanrn Jan 16, 2024
31b435e
Fixed the code documentation or comment
khanrn Jan 16, 2024
eb375ee
Fixed the code documentation or comment
khanrn Jan 16, 2024
5612d88
Renamed property to make more generic
khanrn Jan 17, 2024
54b60af
Tweaks needed for the property name change
khanrn Jan 17, 2024
4f515f9
SMS template post valid scope accepted test
khanrn Jan 17, 2024
1495a6b
Reverting last wrong commit
khanrn Jan 17, 2024
2ca241c
Added unit test default SMS sender
khanrn Jan 17, 2024
b0051de
Renamed some tests to mark them specific for email
khanrn Jan 17, 2024
2c8af52
SMS test for expected register notificaiton order
khanrn Jan 17, 2024
96c15c0
SMS test for no sender handle and default inserted
khanrn Jan 17, 2024
e66ed72
Renamed SenderHandle to SenderNumber again as agreed
khanrn Jan 18, 2024
e3f24d3
Renamed NotificationOrderConfig default proporty for SMS as agreed
khanrn Jan 18, 2024
4bb202a
Renamed _orderService to _orderRequestService
khanrn Jan 18, 2024
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
Expand Up @@ -9,4 +9,9 @@ public class NotificationOrderConfig
/// Default from address for email notifications
/// </summary>
public string DefaultEmailFromAddress { get; set; } = string.Empty;

/// <summary>
/// Default sender number for sms notifications
/// </summary>
public string DefaultSmsSenderNumber { get; set; } = string.Empty;
}
7 changes: 6 additions & 1 deletion src/Altinn.Notifications.Core/Enums/NotificationChannel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,10 @@ public enum NotificationChannel
/// <summary>
/// The selected channel for the notification is email.
/// </summary>
Email
Email,

/// <summary>
/// The selected channel for the notification is SMS.
/// </summary>
Sms
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
/// </summary>
public enum NotificationTemplateType
{
Email
Email,
Sms
}
#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public static void AddCoreServices(this IServiceCollection services, IConfigurat
.AddSingleton<IDateTimeService, DateTimeService>()
.AddSingleton<IOrderProcessingService, OrderProcessingService>()
.AddSingleton<IGetOrderService, GetOrderService>()
.AddSingleton<IEmailNotificationOrderService, EmailNotificationOrderService>()
.AddSingleton<IOrderRequestService, OrderRequestService>()
.AddSingleton<INotificationSummaryService, NotificationSummaryService>()
.AddSingleton<IEmailNotificationService, EmailNotificationService>()
.AddSingleton<IAltinnServiceUpdateService, AltinnServiceUpdateService>()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ namespace Altinn.Notifications.Core.Models.NotificationTemplate;
/// Base class for a notification template
/// </summary>
[JsonDerivedType(typeof(EmailTemplate), "email")]
[JsonDerivedType(typeof(SmsTemplate), "sms")]
[JsonPolymorphic(TypeDiscriminatorPropertyName = "$")]
public interface INotificationTemplate
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using Altinn.Notifications.Core.Enums;

namespace Altinn.Notifications.Core.Models.NotificationTemplate;

/// <summary>
/// Template for an SMS notification
/// </summary>
public class SmsTemplate : INotificationTemplate
{
/// <inheritdoc/>
public NotificationTemplateType Type { get; internal set; }

/// <summary>
/// Gets the number from which the SMS is created by the template
/// </summary>
public string SenderNumber { get; internal set; } = string.Empty;
khanrn marked this conversation as resolved.
Show resolved Hide resolved

/// <summary>
/// Gets the body of SMSs created by the template
/// </summary>
public string Body { get; internal set; } = string.Empty;

/// <summary>
/// Initializes a new instance of the <see cref="SmsTemplate"/> class.
/// </summary>
public SmsTemplate(string? senderNumber, string body)
{
SenderNumber = senderNumber ?? string.Empty;
Body = body;
Type = NotificationTemplateType.Sms;
}

/// <summary>
/// Initializes a new instance of the <see cref="SmsTemplate"/> class.
/// </summary>
internal SmsTemplate()
{
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
namespace Altinn.Notifications.Core.Services.Interfaces;

/// <summary>
/// Interface for the email notification order service
/// Interface for the notification order service
/// </summary>
public interface IEmailNotificationOrderService
public interface IOrderRequestService
{
/// <summary>
/// Registers a new order
/// </summary>
/// <param name="orderRequest">The email notification order request</param>
/// <param name="orderRequest">The notification order request</param>
/// <returns>The registered notification order</returns>
public Task<(NotificationOrder? Order, ServiceError? Error)> RegisterEmailNotificationOrder(NotificationOrderRequest orderRequest);
public Task<(NotificationOrder? Order, ServiceError? Error)> RegisterNotificationOrder(NotificationOrderRequest orderRequest);
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,33 +10,35 @@
namespace Altinn.Notifications.Core.Services;

/// <summary>
/// Implementation of the <see cref="IEmailNotificationOrderService"/>.
/// Implementation of the <see cref="IOrderRequestService"/>.
/// </summary>
public class EmailNotificationOrderService : IEmailNotificationOrderService
public class OrderRequestService : IOrderRequestService
{
private readonly IOrderRepository _repository;
private readonly IGuidService _guid;
private readonly IDateTimeService _dateTime;
private readonly string _defaultFromAddress;
private readonly string _defaultEmailFromAddress;
private readonly string _defaultSmsSender;

/// <summary>
/// Initializes a new instance of the <see cref="EmailNotificationOrderService"/> class.
/// Initializes a new instance of the <see cref="OrderRequestService"/> class.
/// </summary>
public EmailNotificationOrderService(IOrderRepository repository, IGuidService guid, IDateTimeService dateTime, IOptions<NotificationOrderConfig> config)
public OrderRequestService(IOrderRepository repository, IGuidService guid, IDateTimeService dateTime, IOptions<NotificationOrderConfig> config)
{
_repository = repository;
_guid = guid;
_dateTime = dateTime;
_defaultFromAddress = config.Value.DefaultEmailFromAddress;
_defaultEmailFromAddress = config.Value.DefaultEmailFromAddress;
_defaultSmsSender = config.Value.DefaultSmsSenderNumber;
}

/// <inheritdoc/>
public async Task<(NotificationOrder? Order, ServiceError? Error)> RegisterEmailNotificationOrder(NotificationOrderRequest orderRequest)
public async Task<(NotificationOrder? Order, ServiceError? Error)> RegisterNotificationOrder(NotificationOrderRequest orderRequest)
{
Guid orderId = _guid.NewGuid();
DateTime created = _dateTime.UtcNow();

var templates = SetFromAddressIfNotDefined(orderRequest.Templates);
var templates = SetSenderIfNotDefined(orderRequest.Templates);

var order = new NotificationOrder(
orderId,
Expand All @@ -53,11 +55,16 @@ public EmailNotificationOrderService(IOrderRepository repository, IGuidService g
return (savedOrder, null);
}

private List<INotificationTemplate> SetFromAddressIfNotDefined(List<INotificationTemplate> templates)
private List<INotificationTemplate> SetSenderIfNotDefined(List<INotificationTemplate> templates)
{
foreach (var template in templates.OfType<EmailTemplate>().Where(template => string.IsNullOrEmpty(template.FromAddress)))
{
template.FromAddress = _defaultFromAddress;
template.FromAddress = _defaultEmailFromAddress;
}

foreach (var template in templates.OfType<SmsTemplate>().Where(template => string.IsNullOrEmpty(template.SenderNumber)))
{
template.SenderNumber = _defaultSmsSender;
}

khanrn marked this conversation as resolved.
Show resolved Hide resolved
return templates;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,15 @@ namespace Altinn.Notifications.Controllers;
public class EmailNotificationOrdersController : ControllerBase
{
private readonly IValidator<EmailNotificationOrderRequestExt> _validator;
private readonly IEmailNotificationOrderService _orderService;
private readonly IOrderRequestService _orderRequestService;

/// <summary>
/// Initializes a new instance of the <see cref="EmailNotificationOrdersController"/> class.
/// </summary>
public EmailNotificationOrdersController(IValidator<EmailNotificationOrderRequestExt> validator, IEmailNotificationOrderService orderService)
public EmailNotificationOrdersController(IValidator<EmailNotificationOrderRequestExt> validator, IOrderRequestService orderRequestService)
{
_validator = validator;
_orderService = orderService;
_orderRequestService = orderRequestService;
}

/// <summary>
Expand Down Expand Up @@ -71,7 +71,7 @@ public async Task<ActionResult<OrderIdExt>> Post(EmailNotificationOrderRequestEx
}

var orderRequest = emailNotificationOrderRequest.MapToOrderRequest(creator);
(NotificationOrder? registeredOrder, ServiceError? error) = await _orderService.RegisterEmailNotificationOrder(orderRequest);
(NotificationOrder? registeredOrder, ServiceError? error) = await _orderRequestService.RegisterNotificationOrder(orderRequest);

if (error != null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,8 @@ public async Task Post_UserClaimsPrincipal_Forbidden()
public async Task Post_ServiceReturnsError_ServerError()
{
// Arrange
Mock<IEmailNotificationOrderService> serviceMock = new();
serviceMock.Setup(s => s.RegisterEmailNotificationOrder(It.IsAny<NotificationOrderRequest>()))
Mock<IOrderRequestService> serviceMock = new();
serviceMock.Setup(s => s.RegisterNotificationOrder(It.IsAny<NotificationOrderRequest>()))
.ReturnsAsync((null, new ServiceError(500)));

HttpClient client = GetTestClient(orderService: serviceMock.Object);
Expand All @@ -196,8 +196,8 @@ public async Task Post_ServiceReturnsError_ServerError()
public async Task Post_ValidScope_ServiceReturnsOrder_Accepted()
{
// Arrange
Mock<IEmailNotificationOrderService> serviceMock = new();
serviceMock.Setup(s => s.RegisterEmailNotificationOrder(It.IsAny<NotificationOrderRequest>()))
Mock<IOrderRequestService> serviceMock = new();
serviceMock.Setup(s => s.RegisterNotificationOrder(It.IsAny<NotificationOrderRequest>()))
.Callback<NotificationOrderRequest>(orderRequest =>
{
var emailTemplate = orderRequest.Templates
Expand Down Expand Up @@ -235,8 +235,8 @@ public async Task Post_ValidScope_ServiceReturnsOrder_Accepted()
public async Task Post_ValidAccessToken_ServiceReturnsOrder_Accepted()
{
// Arrange
Mock<IEmailNotificationOrderService> serviceMock = new();
serviceMock.Setup(s => s.RegisterEmailNotificationOrder(It.IsAny<NotificationOrderRequest>()))
Mock<IOrderRequestService> serviceMock = new();
serviceMock.Setup(s => s.RegisterNotificationOrder(It.IsAny<NotificationOrderRequest>()))
.Callback<NotificationOrderRequest>(orderRequest =>
{
var emailTemplate = orderRequest.Templates
Expand Down Expand Up @@ -274,9 +274,9 @@ public async Task Post_ValidAccessToken_ServiceReturnsOrder_Accepted()
public async Task Post_OrderWithoutFromAddress_StringEmptyUsedAsServiceInput_Accepted()
{
// Arrange
Mock<IEmailNotificationOrderService> serviceMock = new();
Mock<IOrderRequestService> serviceMock = new();

serviceMock.Setup(s => s.RegisterEmailNotificationOrder(It.IsAny<NotificationOrderRequest>()))
serviceMock.Setup(s => s.RegisterNotificationOrder(It.IsAny<NotificationOrderRequest>()))
.Callback<NotificationOrderRequest>(orderRequest =>
{
var emailTemplate = orderRequest.Templates
Expand Down Expand Up @@ -321,7 +321,7 @@ public async Task Post_OrderWithoutFromAddress_StringEmptyUsedAsServiceInput_Acc
serviceMock.VerifyAll();
}

private HttpClient GetTestClient(IValidator<EmailNotificationOrderRequestExt>? validator = null, IEmailNotificationOrderService? orderService = null)
private HttpClient GetTestClient(IValidator<EmailNotificationOrderRequestExt>? validator = null, IOrderRequestService? orderService = null)
{
if (validator == null)
{
Expand All @@ -333,7 +333,7 @@ private HttpClient GetTestClient(IValidator<EmailNotificationOrderRequestExt>? v

if (orderService == null)
{
var orderServiceMock = new Mock<IEmailNotificationOrderService>();
var orderServiceMock = new Mock<IOrderRequestService>();
orderService = orderServiceMock.Object;
}

Expand Down
Loading
Loading