diff --git a/src/Altinn.Notifications.Core/Models/Notification/EmailNotificationWithResult.cs b/src/Altinn.Notifications.Core/Models/Notification/EmailNotificationWithResult.cs index 0f9ef433..23146430 100644 --- a/src/Altinn.Notifications.Core/Models/Notification/EmailNotificationWithResult.cs +++ b/src/Altinn.Notifications.Core/Models/Notification/EmailNotificationWithResult.cs @@ -10,16 +10,16 @@ namespace Altinn.Notifications.Core.Models.Notification public class EmailNotificationWithResult : INotificationWithResult { /// - public Guid Id { get; internal set; } + public Guid Id { get; } /// public bool Succeeded { get; internal set; } /// - public EmailRecipient Recipient { get; internal set; } + public EmailRecipient Recipient { get; } /// - public NotificationResult ResultStatus { get; internal set; } + public NotificationResult ResultStatus { get; } /// /// Initializes a new instance of the class. @@ -30,5 +30,16 @@ public EmailNotificationWithResult(Guid id, EmailRecipient recipient, Notificati Recipient = recipient; ResultStatus = result; } + + /// + /// Initializes a new instance of the class. + /// + internal EmailNotificationWithResult(Guid id, bool succeeded, EmailRecipient recipient, NotificationResult result) + { + Id = id; + Succeeded = succeeded; + Recipient = recipient; + ResultStatus = result; + } } } diff --git a/src/Altinn.Notifications.Core/Services/NotificationSummaryService.cs b/src/Altinn.Notifications.Core/Services/NotificationSummaryService.cs index f1d09fee..f82bd3fd 100644 --- a/src/Altinn.Notifications.Core/Services/NotificationSummaryService.cs +++ b/src/Altinn.Notifications.Core/Services/NotificationSummaryService.cs @@ -59,10 +59,12 @@ private void ProcessNotificationResults(EmailNotificationSummary summary) { summary.Generated = summary.Notifications.Count; - foreach (NotificationResult resultStatus in summary.Notifications.Select(n => n.ResultStatus)) + foreach (EmailNotificationWithResult notification in summary.Notifications) { + NotificationResult resultStatus = notification.ResultStatus; if (_successResults.Contains(resultStatus.Result)) { + notification.Succeeded = true; ++summary.Succeeded; } diff --git a/src/Altinn.Notifications/Mappers/NotificationSummaryMapper.cs b/src/Altinn.Notifications/Mappers/NotificationSummaryMapper.cs index b281909a..4f6a11a7 100644 --- a/src/Altinn.Notifications/Mappers/NotificationSummaryMapper.cs +++ b/src/Altinn.Notifications/Mappers/NotificationSummaryMapper.cs @@ -27,28 +27,31 @@ public static EmailNotificationSummaryExt MapToEmailNotificationSummaryExt(this /// public static List MapToEmailNotificationWithResultExt(this List notifications) { - List result = new List(); + List result = notifications.Select(n => n.MapToEmailNotificationWithResultExt()).ToList(); - foreach (var notification in notifications) + return result; + } + + /// + /// Maps a to a + /// + public static EmailNotificationWithResultExt MapToEmailNotificationWithResultExt(this EmailNotificationWithResult notification) + { + return new EmailNotificationWithResultExt() { - result.Add(new EmailNotificationWithResultExt() + Id = notification.Id, + Succeeded = notification.Succeeded, + Recipient = new() { - Id = notification.Id, - Succeeded = notification.Succeeded, - Recipient = new() - { - EmailAddress = notification.Recipient.ToAddress - }, - SendStatus = new() - { - Status = notification.ResultStatus.Result.ToString(), - StatusDescription = notification.ResultStatus.ResultDescription, - LastUpdate = notification.ResultStatus.ResultTime - } - }); - } - - return result; + EmailAddress = notification.Recipient.ToAddress + }, + SendStatus = new() + { + Status = notification.ResultStatus.Result.ToString(), + StatusDescription = notification.ResultStatus.ResultDescription, + LastUpdate = notification.ResultStatus.ResultTime + } + }; } } } diff --git a/src/Altinn.Notifications/Models/EmailNotificationSummaryExt.cs b/src/Altinn.Notifications/Models/EmailNotificationSummaryExt.cs index f6e2f606..3131a17e 100644 --- a/src/Altinn.Notifications/Models/EmailNotificationSummaryExt.cs +++ b/src/Altinn.Notifications/Models/EmailNotificationSummaryExt.cs @@ -1,7 +1,5 @@ using System.Text.Json.Serialization; -using Altinn.Notifications.Models; - namespace Altinn.Notifications.Core.Models.Notification { /// @@ -15,56 +13,31 @@ public class EmailNotificationSummaryExt /// /// The order id /// + [JsonPropertyName("orderId")] public Guid OrderId { get; set; } /// /// The senders reference /// + [JsonPropertyName("sendersReference")] public string? SendersReference { get; set; } /// /// The number of generated email notifications /// + [JsonPropertyName("generated")] public int Generated { get; set; } /// /// The number of email notifications that were sent successfully /// + [JsonPropertyName("succeeded")] public int Succeeded { get; set; } /// /// A list of notifications with send result /// + [JsonPropertyName("notifications")] public List Notifications { get; set; } = new List(); } - - /// - /// EmailNotificationWithResultExt class - /// - public class EmailNotificationWithResultExt - { - /// - /// The notification id - /// - [JsonPropertyName("id")] - public Guid Id { get; set; } - - /// - /// Boolean indicating if the sending of the notification was successful - /// - [JsonPropertyName("succeeded")] - public bool Succeeded { get; set; } - - /// - /// The recipient of the notification - /// - [JsonPropertyName("recipient")] - public RecipientExt Recipient { get; set; } = new(); - - /// - /// The result status of the notification - /// - [JsonPropertyName("sendStatus")] - public StatusExt SendStatus { get; set; } = new(); - } } diff --git a/src/Altinn.Notifications/Models/EmailNotificationWithResultExt.cs b/src/Altinn.Notifications/Models/EmailNotificationWithResultExt.cs new file mode 100644 index 00000000..49922d59 --- /dev/null +++ b/src/Altinn.Notifications/Models/EmailNotificationWithResultExt.cs @@ -0,0 +1,36 @@ +using System.Text.Json.Serialization; + +using Altinn.Notifications.Models; + +namespace Altinn.Notifications.Core.Models.Notification +{ + /// + /// EmailNotificationWithResultExt class + /// + public class EmailNotificationWithResultExt + { + /// + /// The notification id + /// + [JsonPropertyName("id")] + public Guid Id { get; set; } + + /// + /// Boolean indicating if the sending of the notification was successful + /// + [JsonPropertyName("succeeded")] + public bool Succeeded { get; set; } + + /// + /// The recipient of the notification + /// + [JsonPropertyName("recipient")] + public RecipientExt Recipient { get; set; } = new(); + + /// + /// The result status of the notification + /// + [JsonPropertyName("sendStatus")] + public StatusExt SendStatus { get; set; } = new(); + } +} diff --git a/test/Altinn.Notifications.IntegrationTests/Notifications.Integrations/TestingConsumers/EmailStatusConsumerTests.cs b/test/Altinn.Notifications.IntegrationTests/Notifications.Integrations/TestingConsumers/EmailStatusConsumerTests.cs index c2140aa6..59af240c 100644 --- a/test/Altinn.Notifications.IntegrationTests/Notifications.Integrations/TestingConsumers/EmailStatusConsumerTests.cs +++ b/test/Altinn.Notifications.IntegrationTests/Notifications.Integrations/TestingConsumers/EmailStatusConsumerTests.cs @@ -60,9 +60,7 @@ public async Task DisposeAsync() protected virtual async Task Dispose(bool disposing) { - string sql = $"delete from notifications.orders where sendersreference = '{_sendersRef}'"; - - await PostgreUtil.RunSql(sql); + await PostgreUtil.DeleteOrderFromDb(_sendersRef); await KafkaUtil.DeleteTopicAsync(_statusUpdatedTopicName); } diff --git a/test/Altinn.Notifications.IntegrationTests/Notifications.Integrations/TestingConsumers/PastDueOrdersConsumerTests.cs b/test/Altinn.Notifications.IntegrationTests/Notifications.Integrations/TestingConsumers/PastDueOrdersConsumerTests.cs index 17e6d8f2..0435f42f 100644 --- a/test/Altinn.Notifications.IntegrationTests/Notifications.Integrations/TestingConsumers/PastDueOrdersConsumerTests.cs +++ b/test/Altinn.Notifications.IntegrationTests/Notifications.Integrations/TestingConsumers/PastDueOrdersConsumerTests.cs @@ -59,8 +59,7 @@ public async void Dispose() protected virtual async Task Dispose(bool disposing) { - string sql = $"delete from notifications.orders where sendersreference = '{_sendersRef}'"; - await PostgreUtil.RunSql(sql); + await PostgreUtil.DeleteOrderFromDb(_sendersRef); await KafkaUtil.DeleteTopicAsync(_pastDueOrdersTopicName); } diff --git a/test/Altinn.Notifications.IntegrationTests/Notifications.Integrations/TestingConsumers/PastDueOrdersRetryConsumerTests.cs b/test/Altinn.Notifications.IntegrationTests/Notifications.Integrations/TestingConsumers/PastDueOrdersRetryConsumerTests.cs index 5abe3eea..d4f928b4 100644 --- a/test/Altinn.Notifications.IntegrationTests/Notifications.Integrations/TestingConsumers/PastDueOrdersRetryConsumerTests.cs +++ b/test/Altinn.Notifications.IntegrationTests/Notifications.Integrations/TestingConsumers/PastDueOrdersRetryConsumerTests.cs @@ -95,8 +95,7 @@ public async void Dispose() protected virtual async Task Dispose(bool disposing) { await KafkaUtil.DeleteTopicAsync(_retryTopicName); - string sql = $"delete from notifications.orders where sendersreference = '{_sendersRef}'"; - await PostgreUtil.RunSql(sql); + await PostgreUtil.DeleteOrderFromDb(_sendersRef); } private static async Task SelectCompletedOrderCount(Guid orderId) diff --git a/test/Altinn.Notifications.IntegrationTests/Notifications/EmailNotificationsController/EmailNotificationsControllerTests.cs b/test/Altinn.Notifications.IntegrationTests/Notifications/EmailNotificationsController/EmailNotificationsControllerTests.cs new file mode 100644 index 00000000..b5fa7c3f --- /dev/null +++ b/test/Altinn.Notifications.IntegrationTests/Notifications/EmailNotificationsController/EmailNotificationsControllerTests.cs @@ -0,0 +1,232 @@ +using System.Net; +using System.Net.Http.Headers; +using System.Text; +using System.Text.Json; + +using Altinn.Common.AccessToken.Services; +using Altinn.Notifications.Configuration; +using Altinn.Notifications.Core.Models; +using Altinn.Notifications.Core.Models.Notification; +using Altinn.Notifications.Core.Services.Interfaces; +using Altinn.Notifications.Tests.Notifications.Mocks.Authentication; +using Altinn.Notifications.Tests.Notifications.Utils; + +using AltinnCore.Authentication.JwtCookie; + +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.TestHost; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using Microsoft.IdentityModel.Logging; + +using Moq; + +using Xunit; + +namespace Altinn.Notifications.IntegrationTests.Notifications.EmailNotificationsController; + +public class EmailNotificationsControllerTests : IClassFixture> +{ + private readonly string _basePath; + private readonly string _invalidGuidBase; + private readonly IntegrationTestWebApplicationFactory _factory; + + private readonly JsonSerializerOptions _options; + + public EmailNotificationsControllerTests(IntegrationTestWebApplicationFactory factory) + { + _basePath = $"/notifications/api/v1/orders/{Guid.NewGuid()}/notifications/email"; + _invalidGuidBase = "/notifications/api/v1/orders/1337;1=1/notifications/email"; + _factory = factory; + _options = new JsonSerializerOptions + { + PropertyNameCaseInsensitive = true + }; + } + + [Fact] + public async Task Get_MissingBearerToken_Unauthorized() + { + // Arrange + HttpClient client = GetTestClient(); + HttpRequestMessage httpRequestMessage = new(HttpMethod.Get, _basePath); + + // Act + HttpResponseMessage response = await client.SendAsync(httpRequestMessage); + + // Assert + Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode); + } + + [Fact] + public async Task Get_InvalidScopeInToken_Forbidden() + { + // Arrange + HttpClient client = GetTestClient(); + client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", PrincipalUtil.GetOrgToken("ttd", scope: "altinn:dummmy.scope")); + HttpRequestMessage httpRequestMessage = new(HttpMethod.Get, _basePath); + + // Act + HttpResponseMessage response = await client.SendAsync(httpRequestMessage); + + // Assert + Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode); + } + + [Fact] + public async Task Get_UserClaimsPrincipal_Forbidden() + { + // Arrange + HttpClient client = GetTestClient(); + client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", PrincipalUtil.GetUserToken(1337)); + + HttpRequestMessage httpRequestMessage = new(HttpMethod.Get, _basePath); + + // Act + HttpResponseMessage response = await client.SendAsync(httpRequestMessage); + + // Assert + Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode); + } + + [Fact] + public async Task Get_InvalidGuid_BadRequest() + { + HttpClient client = GetTestClient(); + client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", PrincipalUtil.GetOrgToken("ttd", scope: "altinn:serviceowner/notifications.create")); + + HttpRequestMessage httpRequestMessage = new(HttpMethod.Get, _invalidGuidBase) + { + Content = new StringContent(string.Empty, Encoding.UTF8, "application/json") + }; + + // Act + HttpResponseMessage response = await client.SendAsync(httpRequestMessage); + + string content = await response.Content.ReadAsStringAsync(); + ProblemDetails? actual = JsonSerializer.Deserialize(content, _options); + + // Assert + Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); + Assert.Equal("One or more validation errors occurred.", actual?.Title); + } + + [Fact] + public async Task Get_ServiceReturnsError_ServerError() + { + // Arrange + Mock serviceMock = new(); + serviceMock.Setup(s => s.GetEmailSummary(It.IsAny(), It.IsAny())) + .ReturnsAsync((null, new ServiceError(500))); + + HttpClient client = GetTestClient(summaryService: serviceMock.Object); + client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", PrincipalUtil.GetOrgToken("ttd", scope: "altinn:serviceowner/notifications.create")); + + HttpRequestMessage httpRequestMessage = new(HttpMethod.Get, _basePath); + + // Act + HttpResponseMessage response = await client.SendAsync(httpRequestMessage); + + // Assert + Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode); + serviceMock.VerifyAll(); + } + + [Fact] + public async Task Get_ValidScope_ServiceReturnsNotifications_Ok() + { + // Arrange + Guid id = Guid.NewGuid(); + EmailNotificationSummary output = new EmailNotificationSummary(id) + { + SendersReference = "senders-ref", + Generated = 1, + Succeeded = 1, + Notifications = new List() + }; + + Mock serviceMock = new(); + serviceMock.Setup(s => s.GetEmailSummary(It.IsAny(), It.Is(s => s.Equals("ttd")))) + .ReturnsAsync((output, null)); + + HttpClient client = GetTestClient(summaryService: serviceMock.Object); + client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", PrincipalUtil.GetOrgToken("ttd", scope: "altinn:serviceowner/notifications.create")); + + HttpRequestMessage httpRequestMessage = new(HttpMethod.Get, _basePath); + + // Act + HttpResponseMessage response = await client.SendAsync(httpRequestMessage); + string respoonseString = await response.Content.ReadAsStringAsync(); + + // Assert + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + + EmailNotificationSummaryExt? summaryExt = JsonSerializer.Deserialize(respoonseString); + Assert.NotNull(summaryExt); + Assert.Equal(id, summaryExt.OrderId); + + serviceMock.VerifyAll(); + } + + [Fact] + public async Task Get_ValidAccessToken_ServiceReturnsOrder_Accepted() + { + // Arrange + Guid id = Guid.NewGuid(); + EmailNotificationSummary output = new EmailNotificationSummary(id) + { + SendersReference = "senders-ref", + Generated = 1, + Succeeded = 1, + Notifications = new List() + }; + + Mock serviceMock = new(); + serviceMock.Setup(s => s.GetEmailSummary(It.IsAny(), It.Is(s => s.Equals("ttd")))) + .ReturnsAsync((output, null)); + + HttpClient client = GetTestClient(summaryService: serviceMock.Object); + client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", PrincipalUtil.GetOrgToken("ttd", scope: "altinn:serviceowner/notifications.create")); + + HttpRequestMessage httpRequestMessage = new(HttpMethod.Get, _basePath); + httpRequestMessage.Headers.Add("PlatformAccessToken", PrincipalUtil.GetAccessToken("ttd", "apps-test")); + + // Act + HttpResponseMessage response = await client.SendAsync(httpRequestMessage); + string respoonseString = await response.Content.ReadAsStringAsync(); + + // Assert + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + + EmailNotificationSummaryExt? summaryExt = JsonSerializer.Deserialize(respoonseString); + Assert.NotNull(summaryExt); + Assert.Equal(id, summaryExt.OrderId); + + serviceMock.VerifyAll(); + } + + private HttpClient GetTestClient(INotificationSummaryService? summaryService = null) + { + if (summaryService == null) + { + var summaryServiceMock = new Mock(); + summaryService = summaryServiceMock.Object; + } + + HttpClient client = _factory.WithWebHostBuilder(builder => + { + IdentityModelEventSource.ShowPII = true; + + builder.ConfigureTestServices(services => + { + services.AddSingleton(summaryService); + + // Set up mock authentication and authorization + services.AddSingleton, JwtCookiePostConfigureOptionsStub>(); + services.AddSingleton(); + }); + }).CreateClient(); + + return client; + } +} diff --git a/test/Altinn.Notifications.IntegrationTests/Notifications/EmailNotificationsController/GetTests.cs b/test/Altinn.Notifications.IntegrationTests/Notifications/EmailNotificationsController/GetTests.cs new file mode 100644 index 00000000..0e74f49b --- /dev/null +++ b/test/Altinn.Notifications.IntegrationTests/Notifications/EmailNotificationsController/GetTests.cs @@ -0,0 +1,132 @@ +using System.Net; +using System.Net.Http.Headers; +using System.Text.Json; + +using Altinn.Common.AccessToken.Services; +using Altinn.Notifications.Core.Models.Notification; +using Altinn.Notifications.Core.Models.Orders; +using Altinn.Notifications.IntegrationTests.Utils; +using Altinn.Notifications.Tests.Notifications.Mocks.Authentication; +using Altinn.Notifications.Tests.Notifications.Utils; + +using AltinnCore.Authentication.JwtCookie; + +using Microsoft.AspNetCore.TestHost; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using Microsoft.IdentityModel.Logging; + +using Xunit; + +namespace Altinn.Notifications.IntegrationTests.Notifications.EmailNotificationsController +{ + public class GetTests : IClassFixture>, IAsyncLifetime + { + private readonly string _basePath; + private readonly IntegrationTestWebApplicationFactory _factory; + private readonly Task _initializeTask; + private Guid _orderId; + private Guid _notificationId; + + public GetTests(IntegrationTestWebApplicationFactory factory) + { + _basePath = $"/notifications/api/v1/orders"; + _factory = factory; + _initializeTask = InitializeAsync(); + } + + public async Task InitializeAsync() + { + (NotificationOrder persistedOrder, EmailNotification persistedNotification) = await PostgreUtil.PopulateDBWithOrderAndEmailNotification(); + _orderId = persistedOrder.Id; + _notificationId = persistedNotification.Id; + } + + async Task IAsyncLifetime.DisposeAsync() + { + string sql = $"delete from notifications.orders where alternateid= '{_orderId}'"; + + await PostgreUtil.RunSql(sql); + } + + [Fact] + public async Task Get_NonExistingOrder_NotFound() + { + // Arrange + string uri = $"{_basePath}/{Guid.NewGuid()}/notifications/email"; + + HttpClient client = GetTestClient(); + client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", PrincipalUtil.GetOrgToken("ttd", scope: "altinn:serviceowner/notifications.create")); + + HttpRequestMessage httpRequestMessage = new(HttpMethod.Get, uri); + + // Act + HttpResponseMessage response = await client.SendAsync(httpRequestMessage); + + // Assert + Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); + } + + [Fact] + public async Task Get_OrderIdForAnotherCreator_NotFound() + { + // Arrange + await _initializeTask; + + string uri = $"{_basePath}/{_orderId}/notifications/email"; + + HttpClient client = GetTestClient(); + client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", PrincipalUtil.GetOrgToken("nav", scope: "altinn:serviceowner/notifications.create")); + + HttpRequestMessage httpRequestMessage = new(HttpMethod.Get, uri); + + // Act + HttpResponseMessage response = await client.SendAsync(httpRequestMessage); + + // Assert + Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); + } + + [Fact] + public async Task Get_ValidOrderId_Ok() + { + // Arrange + await _initializeTask; + + string uri = $"{_basePath}/{_orderId}/notifications/email"; + + HttpClient client = GetTestClient(); + client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", PrincipalUtil.GetOrgToken("ttd", scope: "altinn:serviceowner/notifications.create")); + + HttpRequestMessage httpRequestMessage = new(HttpMethod.Get, uri); + + // Act + HttpResponseMessage response = await client.SendAsync(httpRequestMessage); + string responseString = await response.Content.ReadAsStringAsync(); + + // Assert + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + EmailNotificationSummaryExt? summary = JsonSerializer.Deserialize(responseString); + Assert.True(summary?.Notifications.Count > 0); + Assert.Equal(_orderId, summary?.OrderId); + Assert.Equal(_notificationId, summary?.Notifications[0].Id); + } + + private HttpClient GetTestClient() + { + HttpClient client = _factory.WithWebHostBuilder(builder => + { + IdentityModelEventSource.ShowPII = true; + + builder.ConfigureTestServices(services => + { + // Set up mock authentication and authorization + services.AddSingleton, JwtCookiePostConfigureOptionsStub>(); + services.AddSingleton(); + }); + }).CreateClient(); + + return client; + } + } +} diff --git a/test/Altinn.Notifications.IntegrationTests/Notifications/EmailNotificationsOrderController/PostTests.cs b/test/Altinn.Notifications.IntegrationTests/Notifications/EmailNotificationsOrderController/PostTests.cs index 2afd82ee..a2112b8d 100644 --- a/test/Altinn.Notifications.IntegrationTests/Notifications/EmailNotificationsOrderController/PostTests.cs +++ b/test/Altinn.Notifications.IntegrationTests/Notifications/EmailNotificationsOrderController/PostTests.cs @@ -5,7 +5,6 @@ using Altinn.Common.AccessToken.Services; using Altinn.Notifications.Controllers; -using Altinn.Notifications.Core.Enums; using Altinn.Notifications.IntegrationTests.Utils; using Altinn.Notifications.Models; using Altinn.Notifications.Tests.Notifications.Mocks.Authentication; @@ -63,7 +62,7 @@ public PostTests(IntegrationTestWebApplicationFactory PopulateDBWithOrderAndEmailNotificat return o; } + public static async Task DeleteOrderFromDb(string sendersRef) + { + string sql = $"delete from notifications.orders where sendersreference = '{sendersRef}'"; + await PostgreUtil.RunSql(sql); + } + + public static async Task DeleteOrderFromDb(Guid orderId) + { + string sql = $"delete from notifications.orders where alternateid = '{orderId}'"; + await PostgreUtil.RunSql(sql); + } + public static async Task RunSqlReturnIntOutput(string query) { NpgsqlDataSource dataSource = (NpgsqlDataSource)ServiceUtil.GetServices(new List() { typeof(NpgsqlDataSource) })[0]!; diff --git a/test/Altinn.Notifications.Tests/Notifications/TestingMappers/NotificationSummaryMapperTests.cs b/test/Altinn.Notifications.Tests/Notifications/TestingMappers/NotificationSummaryMapperTests.cs new file mode 100644 index 00000000..c58f5332 --- /dev/null +++ b/test/Altinn.Notifications.Tests/Notifications/TestingMappers/NotificationSummaryMapperTests.cs @@ -0,0 +1,114 @@ +using System; +using System.Collections.Generic; + +using Altinn.Notifications.Core.Enums; +using Altinn.Notifications.Core.Models.Notification; +using Altinn.Notifications.Core.Models.Recipients; +using Altinn.Notifications.Mappers; + +using Xunit; + +namespace Altinn.Notifications.Tests.Notifications.TestingMappers +{ + public class NotificationSummaryMapperTests + { + [Fact] + public void MapToEmailNotificationWithResultExt_EmptyList_AreEquivalent() + { + // Arrange + List input = new(); + + // Act + var actual = input.MapToEmailNotificationWithResultExt(); + + // Assert + Assert.Empty(actual); + } + + [Fact] + public void MapToEmailNotificationWithResultExt_NotificationWithFailedResult_AreEquivalent() + { + // Arrange + Guid id = Guid.NewGuid(); + DateTime timestamp = DateTime.UtcNow; + EmailNotificationWithResultExt expected = new() + { + Id = id, + Succeeded = false, + Recipient = new() + { + EmailAddress = "recipient@domain.com" + }, + SendStatus = new() + { + LastUpdate = timestamp, + Status = "Failed_RecipientNotIdentified", + StatusDescription = "Failed to send. Could not identify recipient." + } + }; + + EmailNotificationWithResult input = new( + id, + false, + new EmailRecipient() + { + RecipientId = "12345678910", + ToAddress = "recipient@domain.com" + }, + new NotificationResult( + EmailNotificationResultType.Failed_RecipientNotIdentified, + timestamp)); + + input.ResultStatus.SetResultDescription("Failed to send. Could not identify recipient."); + + // Act + var actual = input.MapToEmailNotificationWithResultExt(); + + // Assert + Assert.Equivalent(expected, actual, false); + } + + [Fact] + public void MapToEmailNotificationWithResultExt_NotificationWithSuccessResult_AreEquivalent() + { + // Arrange + Guid id = Guid.NewGuid(); + DateTime timestamp = DateTime.UtcNow; + EmailNotificationWithResultExt expected = new() + { + Id = id, + Succeeded = true, + Recipient = new() + { + EmailAddress = "recipient@domain.com" + }, + SendStatus = new() + { + LastUpdate = timestamp, + Status = "Delivered", + StatusDescription = "The email was delivered to the recipient. No errors reported, making it likely it was received by the recipient." + } + }; + + EmailNotificationWithResult input = new( + id, + true, + new EmailRecipient() + { + RecipientId = "12345678910", + ToAddress = "recipient@domain.com" + }, + new NotificationResult( + EmailNotificationResultType.Delivered, + timestamp)); + + input.ResultStatus.SetResultDescription("The email was delivered to the recipient. No errors reported, making it likely it was received by the recipient."); + + // Act + var actual = input.MapToEmailNotificationWithResultExt(); + + // Assert + Assert.Equivalent(expected, actual, false); + } + } +}