From ccecc86959a247b13ed743cbda4fd5aa63509b89 Mon Sep 17 00:00:00 2001 From: Norbert Truchsess Date: Fri, 8 Sep 2023 13:02:15 +0200 Subject: [PATCH] cleanup --- .../Mailing.Service/IRoleBaseMailService.cs | 2 +- .../Mailing.Service/RoleBaseMailService.cs | 20 ++++-- .../Offers.Library/Service/OfferService.cs | 27 +++++--- .../Service/OfferSubscriptionService.cs | 19 +++-- .../RoleBaseMailServiceTests.cs | 69 +++++++++++-------- .../Service/OfferServiceTests.cs | 35 ++++++++-- .../Service/OfferSubscriptionServiceTests.cs | 62 ++++++++++++++--- 7 files changed, 171 insertions(+), 63 deletions(-) diff --git a/src/mailing/Mailing.Service/IRoleBaseMailService.cs b/src/mailing/Mailing.Service/IRoleBaseMailService.cs index 60e60fc570..58b71419ab 100644 --- a/src/mailing/Mailing.Service/IRoleBaseMailService.cs +++ b/src/mailing/Mailing.Service/IRoleBaseMailService.cs @@ -24,5 +24,5 @@ namespace Org.Eclipse.TractusX.Portal.Backend.Mailing.Service; public interface IRoleBaseMailService { - public Task RoleBaseSendMail(IEnumerable receiverRoles, IDictionary parameters, IEnumerable template, Guid companyId); + Task RoleBaseSendMail(IEnumerable receiverRoles, IEnumerable<(string ParameterName, string ParameterValue)> parameters, (string ParameterName, string ParameterValue)? userNameParameter, IEnumerable template, Guid companyId); } diff --git a/src/mailing/Mailing.Service/RoleBaseMailService.cs b/src/mailing/Mailing.Service/RoleBaseMailService.cs index 8e47a5037f..395997c64c 100644 --- a/src/mailing/Mailing.Service/RoleBaseMailService.cs +++ b/src/mailing/Mailing.Service/RoleBaseMailService.cs @@ -23,6 +23,7 @@ using Org.Eclipse.TractusX.Portal.Backend.Mailing.SendMail; using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess; using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess.Repositories; +using System.Collections.Immutable; namespace Org.Eclipse.TractusX.Portal.Backend.Mailing.Service; @@ -37,7 +38,7 @@ public RoleBaseMailService(IPortalRepositories portalRepositories, IMailingServi _portalRepositories = portalRepositories; _mailingService = mailingService; } - public async Task RoleBaseSendMail(IEnumerable receiverRoles, IDictionary parameters, IEnumerable template, Guid companyId) + public async Task RoleBaseSendMail(IEnumerable receiverRoles, IEnumerable<(string ParameterName, string ParameterValue)> parameters, (string ParameterName, string ParameterValue)? userNameParameter, IEnumerable template, Guid companyId) { var receiverUserRoles = receiverRoles; var userRolesRepository = _portalRepositories.GetInstance(); @@ -53,16 +54,23 @@ public async Task RoleBaseSendMail(IEnumerable receiverRoles, ID var companyUserWithRoleIdForCompany = _portalRepositories.GetInstance() .GetCompanyUserEmailForCompanyAndRoleId(roleData, companyId); + await foreach (var (receiver, firstName, lastName) in companyUserWithRoleIdForCompany) { - var userName = string.Join(" ", new[] { firstName, lastName }.Where(item => !string.IsNullOrWhiteSpace(item))); - - if (!string.IsNullOrWhiteSpace(userName) && parameters.Keys.Contains("offerProviderName")) + IEnumerable<(string ParameterName, string ParameterValue)> ParametersWithUserName() { - parameters["offerProviderName"] = userName; + if (userNameParameter.HasValue) + { + var userName = string.Join(" ", new[] { firstName, lastName }.Where(item => !string.IsNullOrWhiteSpace(item))); + return parameters.Append( + string.IsNullOrWhiteSpace(userName) + ? userNameParameter.Value + : new(userNameParameter.Value.ParameterName, userName)); + } + return parameters; } - await _mailingService.SendMails(receiver, parameters, template).ConfigureAwait(false); + await _mailingService.SendMails(receiver, ParametersWithUserName().ToImmutableDictionary(x => x.ParameterName, x => x.ParameterValue), template).ConfigureAwait(false); } } } diff --git a/src/marketplace/Offers.Library/Service/OfferService.cs b/src/marketplace/Offers.Library/Service/OfferService.cs index 60aa2b1d61..e5c489643f 100644 --- a/src/marketplace/Offers.Library/Service/OfferService.cs +++ b/src/marketplace/Offers.Library/Service/OfferService.cs @@ -559,21 +559,30 @@ public async Task DeclineOfferAsync(Guid offerId, Guid userId, OfferDeclineReque DeclineMessage = data.Message }; - var serializeNotificationContent = JsonSerializer.Serialize(notificationContent); - var content = Enumerable.Repeat(notificationTypeId, 1).Select(typeId => new ValueTuple(serializeNotificationContent, typeId)); + var content = new (string?, NotificationTypeId)[] + { + (JsonSerializer.Serialize(notificationContent), notificationTypeId) + }; + await _notificationService.CreateNotifications(notificationRecipients, userId, content, declineData.CompanyId.Value).AwaitAll().ConfigureAwait(false); await _notificationService.SetNotificationsForOfferToDone(catenaAdminRoles, submitOfferNotificationTypeIds, offerId).ConfigureAwait(false); await _portalRepositories.SaveAsync().ConfigureAwait(false); - var mailParams = new Dictionary + await _roleBaseMailService.RoleBaseSendMail( + notificationRecipients, + new[] { - { "offerName", declineData.OfferName }, - { "url", basePortalAddress }, - { "declineMessage", data.Message }, - { "offerProviderName", "Service Manager"}, - }; - await _roleBaseMailService.RoleBaseSendMail(notificationRecipients, mailParams, new List { "offer-request-decline" }, declineData.CompanyId.Value).ConfigureAwait(false); + ("offerName", declineData.OfferName), + ("url", basePortalAddress), + ("declineMessage", data.Message), + }, + ("offerProviderName", "Service Manager"), + new[] + { + "offer-request-decline" + }, + declineData.CompanyId.Value).ConfigureAwait(false); } private async Task CheckLanguageCodesExist(IEnumerable languageCodes) diff --git a/src/marketplace/Offers.Library/Service/OfferSubscriptionService.cs b/src/marketplace/Offers.Library/Service/OfferSubscriptionService.cs index ac6c60d787..ab11c30314 100644 --- a/src/marketplace/Offers.Library/Service/OfferSubscriptionService.cs +++ b/src/marketplace/Offers.Library/Service/OfferSubscriptionService.cs @@ -71,13 +71,20 @@ public async Task AddOfferSubscriptionAsync(Guid offerId, IEnumerable + await _roleBaseMailService.RoleBaseSendMail( + notificationRecipients, + new[] { - { "offerName", offerProviderDetails.OfferName! }, - { "offerProviderName", "User"}, - { "url", basePortalAddress } - }; - await _roleBaseMailService.RoleBaseSendMail(notificationRecipients, mailParams, new List { "subscription-request" }, offerProviderDetails.ProviderCompanyId.Value).ConfigureAwait(false); + ("offerName", offerProviderDetails.OfferName!), + ("url", basePortalAddress) + }, + ("offerProviderName", "User"), + new[] + { + "subscription-request" + }, + offerProviderDetails.ProviderCompanyId.Value).ConfigureAwait(false); + return offerSubscription.Id; } diff --git a/tests/mailing/Mailing.Service.Tests/RoleBaseMailServiceTests.cs b/tests/mailing/Mailing.Service.Tests/RoleBaseMailServiceTests.cs index 350a85b1de..9a53836b82 100644 --- a/tests/mailing/Mailing.Service.Tests/RoleBaseMailServiceTests.cs +++ b/tests/mailing/Mailing.Service.Tests/RoleBaseMailServiceTests.cs @@ -57,37 +57,51 @@ public RoleBaseMailServiceTests() _sut = new RoleBaseMailService(_portalRepositories, _mailingService); } - [Fact] - public async Task RoleBaseSendMail_ReturnsExpectedCalls() + [Theory] + [InlineData(true)] + [InlineData(false)] + public async Task RoleBaseSendMail_WithUserNameParameter_ReturnsExpectedCalls(bool hasUserNameParameter) { // Arrange - var template = new List { "test-request" }; - var mailParams = new Dictionary - { - { "offerName", _fixture.Create() }, - { "url", BasePortalUrl}, - { "offerProviderName", "user"}, - }; - var receiverRoles = new[]{ - new UserRoleConfig("ClientId", new [] { "TestApp Manager", "TestSale Manager" }) + var template = new[] { "test-request" }; + var offerName = _fixture.Create(); + var mailParams = new[] + { + ("offerName", offerName), + ("url", BasePortalUrl) + }; + var userNameParam = hasUserNameParameter + ? ("offerProviderName", "user") + : ((string, string)?)null; + var receiverRoles = new[] + { + new UserRoleConfig("ClientId", new[] { "TestApp Manager", "TestSale Manager" }) }; - var companyUserData = new[]{ - new ValueTuple("TestApp@bmw","AppFirst","AppLast"), - new ValueTuple("TestSale@bmw","SaleFirst","SaleLast") + var companyUserData = new (string, string?, string?)[] + { + ("TestApp@bmw", "AppFirst", "AppLast"), + ("TestSale@bmw", "SaleFirst", "SaleLast") }; - A.CallTo(() => _userRolesRepository.GetUserRoleIdsUntrackedAsync(A>.That.Matches(x => x.Any(y => y.ClientId == "ClientId")))) + A.CallTo(() => _userRolesRepository.GetUserRoleIdsUntrackedAsync(A>._)) .Returns(_userRoleIds.ToAsyncEnumerable()); - A.CallTo(() => _userRepository.GetCompanyUserEmailForCompanyAndRoleId(A>.That.IsSameSequenceAs(_userRoleIds), _companyId)) + A.CallTo(() => _userRepository.GetCompanyUserEmailForCompanyAndRoleId(A>._, A._)) .Returns(companyUserData.ToAsyncEnumerable()); // Act - await _sut.RoleBaseSendMail(receiverRoles, mailParams, template, _companyId); + await _sut.RoleBaseSendMail(receiverRoles, mailParams, userNameParam, template, _companyId); // Assert - A.CallTo(() => _userRolesRepository.GetUserRoleIdsUntrackedAsync(A>._)).MustHaveHappenedOnceExactly(); - A.CallTo(() => _userRepository.GetCompanyUserEmailForCompanyAndRoleId(A>._, _companyId)).MustHaveHappenedOnceExactly(); - A.CallTo(() => _mailingService.SendMails(A._, A>._, A>._)).MustHaveHappenedTwiceExactly(); + A.CallTo(() => _userRolesRepository.GetUserRoleIdsUntrackedAsync(A>.That.Matches(x => x.Any(y => y.ClientId == "ClientId")))).MustHaveHappenedOnceExactly(); + A.CallTo(() => _userRepository.GetCompanyUserEmailForCompanyAndRoleId(A>.That.IsSameSequenceAs(_userRoleIds), _companyId)).MustHaveHappenedOnceExactly(); + A.CallTo(() => _mailingService.SendMails( + "TestApp@bmw", + A>.That.Matches(x => x.Count() == (hasUserNameParameter ? 3 : 2) && x["offerName"] == offerName && x["url"] == BasePortalUrl && (!hasUserNameParameter || x["offerProviderName"] == "AppFirst AppLast")), + A>.That.IsSameSequenceAs(template))).MustHaveHappenedOnceExactly(); + A.CallTo(() => _mailingService.SendMails( + "TestSale@bmw", + A>.That.Matches(x => x.Count() == (hasUserNameParameter ? 3 : 2) && x["offerName"] == offerName && x["url"] == BasePortalUrl && (!hasUserNameParameter || x["offerProviderName"] == "SaleFirst SaleLast")), + A>.That.IsSameSequenceAs(template))).MustHaveHappenedOnceExactly(); } [Fact] @@ -95,12 +109,13 @@ public async Task RoleBaseSendMail_ThrowsConfigurationException() { // Arrange var template = new List { "test-request" }; - var mailParams = new Dictionary - { - { "offerName", _fixture.Create() }, - { "url", BasePortalUrl}, - { "offerProviderName", "user"}, - }; + var mailParams = new[] + { + ("offerName", _fixture.Create()), + ("url", BasePortalUrl), + }; + var userNameParam = ("offerProviderName", "user"); + var roleData = _fixture.CreateMany(1); var receiverRoles = new[]{ new UserRoleConfig("ClientId", new [] { "App Manager", "Sales Manager" }) @@ -110,7 +125,7 @@ public async Task RoleBaseSendMail_ThrowsConfigurationException() .Returns(roleData.ToAsyncEnumerable()); // Act - async Task Action() => await _sut.RoleBaseSendMail(receiverRoles, mailParams, template, _companyId); + async Task Action() => await _sut.RoleBaseSendMail(receiverRoles, mailParams, userNameParam, template, _companyId); // Assert var ex = await Assert.ThrowsAsync(Action); diff --git a/tests/marketplace/Offers.Library.Tests/Service/OfferServiceTests.cs b/tests/marketplace/Offers.Library.Tests/Service/OfferServiceTests.cs index 45a64442e4..065c89eead 100644 --- a/tests/marketplace/Offers.Library.Tests/Service/OfferServiceTests.cs +++ b/tests/marketplace/Offers.Library.Tests/Service/OfferServiceTests.cs @@ -1111,15 +1111,20 @@ public async Task DeclineOfferAsync_WithValidData_CallsExpected(OfferTypeId offe // Arrange var offer = _fixture.Create(); var offerId = _fixture.Create(); - var recipients = new[] { new UserRoleConfig("Test", new[] { "Abc" }) }; + var recipients = new[] + { + new UserRoleConfig("Test", new[] { "Abc" }) + }; var roleIds = _fixture.CreateMany(); var documentStatusDatas = new DocumentStatusData[] { new(Guid.NewGuid(), DocumentStatusId.LOCKED), new(Guid.NewGuid(), DocumentStatusId.PENDING), }; + var companyId = Guid.NewGuid(); + var offerName = _fixture.Create(); A.CallTo(() => _offerRepository.GetOfferDeclineDataAsync(offerId, offerTypeId)) - .Returns(("test", OfferStatusId.IN_REVIEW, Guid.NewGuid(), documentStatusDatas)); + .Returns((offerName, OfferStatusId.IN_REVIEW, companyId, documentStatusDatas)); A.CallTo(() => _offerRepository.AttachAndModifyOffer(offerId, A>._, A?>._)) .Invokes((Guid _, Action setOptionalParameters, Action? initializeParemeters) => { @@ -1129,7 +1134,7 @@ public async Task DeclineOfferAsync_WithValidData_CallsExpected(OfferTypeId offe A.CallTo(() => _userRolesRepository.GetUserRoleIdsUntrackedAsync(A>._)) .Returns(roleIds.ToAsyncEnumerable()); A.CallTo(() => _userRepository.GetCompanyUserEmailForCompanyAndRoleId(A>._, A._)) - .Returns(new (string Email, string? Firstname, string? Lastname)[] { new("test@email.com", "Test User 1", "cx-user-2") }.ToAsyncEnumerable()); + .Returns(new[] { ("test@email.com", (string?)"Test User 1", (string?)"cx-user-2") }.ToAsyncEnumerable()); IEnumerable? initial = null; IEnumerable? modified = null; @@ -1152,15 +1157,35 @@ public async Task DeclineOfferAsync_WithValidData_CallsExpected(OfferTypeId offe ).ToImmutableArray(); }); + var declineMessage = _fixture.Create(); + var basePortalAddress = _fixture.Create(); + + var mailParameters = new[] + { + ("offerName", offerName), + ("url", basePortalAddress), + ("declineMessage", declineMessage) + }; + var userNameParameter = ("offerProviderName", "Service Manager"); + var template = new[] + { + "offer-request-decline" + }; + // Act - await _sut.DeclineOfferAsync(offerId, _identity.UserId, new OfferDeclineRequest("Test"), offerTypeId, NotificationTypeId.SERVICE_RELEASE_REJECTION, recipients, string.Empty, new[] { NotificationTypeId.APP_SUBSCRIPTION_REQUEST }, _fixture.CreateMany()).ConfigureAwait(false); + await _sut.DeclineOfferAsync(offerId, _identity.UserId, new OfferDeclineRequest(declineMessage), offerTypeId, NotificationTypeId.SERVICE_RELEASE_REJECTION, recipients, basePortalAddress, new[] { NotificationTypeId.APP_SUBSCRIPTION_REQUEST }, _fixture.CreateMany()).ConfigureAwait(false); // Assert A.CallTo(() => _offerRepository.AttachAndModifyOffer(offerId, A>._, A?>._)).MustHaveHappenedOnceExactly(); A.CallTo(() => _portalRepositories.SaveAsync()).MustHaveHappenedOnceExactly(); A.CallTo(() => _notificationService.CreateNotifications(A>._, A._, A>._, A._, A._)).MustHaveHappenedOnceExactly(); A.CallTo(() => _createNotificationsEnumerator.MoveNextAsync()).MustHaveHappened(2, Times.Exactly); - A.CallTo(() => _roleBaseMailService.RoleBaseSendMail(A>._, A>._, A>._, A._)).MustHaveHappenedOnceExactly(); + A.CallTo(() => _roleBaseMailService.RoleBaseSendMail( + A>.That.IsSameSequenceAs(recipients), + A>.That.IsSameSequenceAs(mailParameters), + userNameParameter, + A>.That.IsSameSequenceAs(template), + companyId)).MustHaveHappenedOnceExactly(); offer.OfferStatusId.Should().Be(OfferStatusId.CREATED); A.CallTo(() => _documentRepository.AttachAndModifyDocuments(A?, Action)>>._)).MustHaveHappenedOnceExactly(); initial.Should().HaveCount(2).And.Satisfy( diff --git a/tests/marketplace/Offers.Library.Tests/Service/OfferSubscriptionServiceTests.cs b/tests/marketplace/Offers.Library.Tests/Service/OfferSubscriptionServiceTests.cs index dd67a9339c..3707da74f2 100644 --- a/tests/marketplace/Offers.Library.Tests/Service/OfferSubscriptionServiceTests.cs +++ b/tests/marketplace/Offers.Library.Tests/Service/OfferSubscriptionServiceTests.cs @@ -34,7 +34,7 @@ namespace Org.Eclipse.TractusX.Portal.Backend.Offers.Library.Tests.Service; public class OfferSubscriptionServiceTests { - private const string BasePortalUrl = "http//base-url.com"; + private const string BasePortalUrl = "http://base-url.com"; private const string ClientId = "Client1"; private readonly Guid _salesManagerId = new("ac1cf001-7fbc-1f2f-817f-bce058020001"); @@ -119,9 +119,15 @@ public OfferSubscriptionServiceTests() public async Task AddOfferSubscription_WithExistingId_CreatesServiceSubscription(OfferTypeId offerTypeId) { // Arrange - var subscriptionManagerRoles = offerTypeId == OfferTypeId.APP ? new[]{ - new UserRoleConfig(ClientId, new [] { "App Manager", "Sales Manager" })} : new[]{ - new UserRoleConfig(ClientId, new [] { "Service Manager", "Sales Manager" })}; + var subscriptionManagerRoles = offerTypeId == OfferTypeId.APP + ? new[] + { + new UserRoleConfig(ClientId, new[] { "App Manager", "Sales Manager" }) + } + : new[] + { + new UserRoleConfig(ClientId, new[] { "Service Manager", "Sales Manager" }) + }; A.CallTo(() => _offerSubscriptionsRepository.CheckPendingOrActiveSubscriptionExists(A._, A._, A._)) .Returns(false); var companyAssignedApps = new List(); @@ -132,6 +138,17 @@ public async Task AddOfferSubscription_WithExistingId_CreatesServiceSubscription companyAssignedApps.Add(companyAssignedApp); }); + var mailParameters = new[] + { + ("offerName", "Test Offer"), + ("url", BasePortalUrl) + }; + var userParameter = ("offerProviderName", "User"); + var template = new[] + { + "subscription-request" + }; + // Act await _sut.AddOfferSubscriptionAsync(_existingOfferId, _validConsentData, (_identity.UserId, _identity.CompanyId), offerTypeId, BasePortalUrl, subscriptionManagerRoles).ConfigureAwait(false); @@ -142,7 +159,12 @@ public async Task AddOfferSubscription_WithExistingId_CreatesServiceSubscription A.CallTo(() => _offerSubscriptionsRepository.CheckPendingOrActiveSubscriptionExists(_existingOfferId, _companyId, offerTypeId)).MustHaveHappenedOnceExactly(); } A.CallTo(() => _processStepRepository.CreateProcessStepRange(A>.That.Matches(x => x.Count() == 1 && x.Single().ProcessStepTypeId == ProcessStepTypeId.TRIGGER_PROVIDER))).MustHaveHappenedOnceExactly(); - A.CallTo(() => _roleBaseMailService.RoleBaseSendMail(A>._, A>._, A>._, A._)).MustHaveHappenedOnceExactly(); + A.CallTo(() => _roleBaseMailService.RoleBaseSendMail( + A>.That.IsSameSequenceAs(subscriptionManagerRoles), + A>.That.IsSameSequenceAs(mailParameters), + userParameter, + A>.That.IsSameSequenceAs(template), + _companyId)).MustHaveHappenedOnceExactly(); } [Theory] @@ -151,9 +173,16 @@ public async Task AddOfferSubscription_WithExistingId_CreatesServiceSubscription public async Task AddOfferSubscription_WithSalesManagerEqualsReceiver_CreatesServiceSubscription(OfferTypeId offerTypeId) { // Arrange - var subscriptionManagerRoles = offerTypeId == OfferTypeId.APP ? new[]{ - new UserRoleConfig("portal", new [] { "App Manager", "Sales Manager" })} : new[]{ - new UserRoleConfig("portal", new [] { "Service Manager", "Sales Manager" })}; + var subscriptionManagerRoles = offerTypeId == OfferTypeId.APP + ? new[] + { + new UserRoleConfig("portal", new[] { "App Manager", "Sales Manager" }) + } + : new[] + { + new UserRoleConfig("portal", new[] { "Service Manager", "Sales Manager" }) + }; + var offerProviderDetails = _fixture.Create(); A.CallTo(() => _offerSubscriptionsRepository.CheckPendingOrActiveSubscriptionExists(A._, A._, A._)) .Returns(false); var companyAssignedApps = new List(); @@ -163,13 +192,28 @@ public async Task AddOfferSubscription_WithSalesManagerEqualsReceiver_CreatesSer var companyAssignedApp = new OfferSubscription(_newOfferSubscriptionId, offerId, companyId, offerSubscriptionStatusId, requesterId); companyAssignedApps.Add(companyAssignedApp); }); + var mailParameters = new[] + { + ("offerName", "Test Offer"), + ("url", BasePortalUrl) + }; + var userParameter = ("offerProviderName", "User"); + var template = new[] + { + "subscription-request" + }; // Act await _sut.AddOfferSubscriptionAsync(_existingOfferId, _validConsentData, (_identity.UserId, _identity.CompanyId), offerTypeId, BasePortalUrl, subscriptionManagerRoles).ConfigureAwait(false); // Assert companyAssignedApps.Should().HaveCount(1); - A.CallTo(() => _roleBaseMailService.RoleBaseSendMail(A>._, A>._, A>._, A._)).MustHaveHappenedOnceExactly(); + A.CallTo(() => _roleBaseMailService.RoleBaseSendMail( + A>.That.IsSameSequenceAs(subscriptionManagerRoles), + A>.That.IsSameSequenceAs(mailParameters), + userParameter, + A>.That.IsSameSequenceAs(template), + _companyId)).MustHaveHappenedOnceExactly(); } [Theory]