From 094de41c0edde9b6e9fbf32365e5d121ed101af6 Mon Sep 17 00:00:00 2001 From: Matt Gibson Date: Tue, 9 Nov 2021 17:51:36 -0500 Subject: [PATCH] Send f4e offer email --- src/Core/Services/IMailService.cs | 6 ++---- .../Implementations/HandlebarsMailService.cs | 16 ++++++++++++--- .../OrganizationSponsorshipService.cs | 8 ++++++-- .../NoopImplementations/NoopMailService.cs | 9 ++------- .../OrganizationSponsorshipServiceTests.cs | 20 +++++++++++++++++-- 5 files changed, 41 insertions(+), 18 deletions(-) diff --git a/src/Core/Services/IMailService.cs b/src/Core/Services/IMailService.cs index c0eb047c1..5e8ea8f3b 100644 --- a/src/Core/Services/IMailService.cs +++ b/src/Core/Services/IMailService.cs @@ -50,10 +50,8 @@ namespace Bit.Core.Services Task SendProviderUserRemoved(string providerName, string email); Task SendUpdatedTempPasswordEmailAsync(string email, string userName); // TODO: Change signature to hold data needed for email - Task SendFamiliesForEnterpriseInviteRedeemableEmailAsync(string email, string organizationName, string token); - // NOTE: Not married to these next two names - Task SendFamiliesForEnterpriseInviteRedeemedToFamilyUserEmailAsync(string email); - Task SendFamiliesForEnterpriseInviteRedeemedToOrgUserEmailAsync(string email, string organizationName); + Task SendFamiliesForEnterpriseOfferEmailAsync(string email, string organizationName, string token); + Task SendFamiliesForEnterpriseRedeemedEmailsAsync(string familyUserEmail, string sponsorEmail, string sponsorOrgName); Task SendFamiliesForEnterpriseReconfirmationRequiredEmailAsync(string email); Task SendFamiliesForEnterpriseSponsorshipRevertingEmailAsync(string email); Task SendFamiliesForEnterpriseSponsorshipEndingEmailAsync(string email); diff --git a/src/Core/Services/Implementations/HandlebarsMailService.cs b/src/Core/Services/Implementations/HandlebarsMailService.cs index ada022a19..a48b458a0 100644 --- a/src/Core/Services/Implementations/HandlebarsMailService.cs +++ b/src/Core/Services/Implementations/HandlebarsMailService.cs @@ -757,7 +757,7 @@ namespace Bit.Core.Services await _mailDeliveryService.SendEmailAsync(message); } - public async Task SendFamiliesForEnterpriseInviteRedeemableEmailAsync(string email, string organizationName, string token) + public async Task SendFamiliesForEnterpriseOfferEmailAsync(string email, string organizationName, string token) { // TODO: Complete emails var message = CreateDefaultMessage("A Family Organization Invite Is Redeemable", email); @@ -780,7 +780,17 @@ namespace Bit.Core.Services await _mailDeliveryService.SendEmailAsync(message); } - public async Task SendFamiliesForEnterpriseInviteRedeemedToFamilyUserEmailAsync(string email) + public async Task SendFamiliesForEnterpriseRedeemedEmailsAsync(string familyUserEmail, string sponsorEmail, string sponsorOrgName) + { + // TODO: complete emails + // Email family user + await SendFamiliesForEnterpriseInviteRedeemedToFamilyUserEmailAsync(familyUserEmail); + + // Email enterprise org user + await SendFamiliesForEnterpriseInviteRedeemedToOrgUserEmailAsync(sponsorEmail, sponsorOrgName); + } + + private async Task SendFamiliesForEnterpriseInviteRedeemedToFamilyUserEmailAsync(string email) { // TODO: Complete emails var message = CreateDefaultMessage("You Have Redeemed A Family Organization Sponsorship", email); @@ -793,7 +803,7 @@ namespace Bit.Core.Services await _mailDeliveryService.SendEmailAsync(message); } - public async Task SendFamiliesForEnterpriseInviteRedeemedToOrgUserEmailAsync(string email, string organizationName) + private async Task SendFamiliesForEnterpriseInviteRedeemedToOrgUserEmailAsync(string email, string organizationName) { // TODO: Complete emails var message = CreateDefaultMessage("A User Has Redeemeed Your Sponsorship", email); diff --git a/src/Core/Services/Implementations/OrganizationSponsorshipService.cs b/src/Core/Services/Implementations/OrganizationSponsorshipService.cs index 72128389a..79250323c 100644 --- a/src/Core/Services/Implementations/OrganizationSponsorshipService.cs +++ b/src/Core/Services/Implementations/OrganizationSponsorshipService.cs @@ -16,16 +16,20 @@ namespace Bit.Core.Services private readonly IOrganizationSponsorshipRepository _organizationSponsorshipRepository; private readonly IOrganizationRepository _organizationRepository; private readonly IPaymentService _paymentService; + private readonly IMailService _mailService; + private readonly IDataProtector _dataProtector; public OrganizationSponsorshipService(IOrganizationSponsorshipRepository organizationSponsorshipRepository, IOrganizationRepository organizationRepository, IPaymentService paymentService, + IMailService mailService, IDataProtectionProvider dataProtectionProvider) { _organizationSponsorshipRepository = organizationSponsorshipRepository; _organizationRepository = organizationRepository; _paymentService = paymentService; + _mailService = mailService; _dataProtector = dataProtectionProvider.CreateProtector("OrganizationSponsorshipServiceDataProtector"); } @@ -87,8 +91,8 @@ namespace Bit.Core.Services { sponsorship = await _organizationSponsorshipRepository.CreateAsync(sponsorship); - // TODO: send email to sponsoredEmail w/ redemption token link - // var _ = RedemptionToken(sponsorship.Id, sponsorshipType); + await _mailService.SendFamiliesForEnterpriseOfferEmailAsync(sponsoredEmail, sponsoringOrg.Name, + RedemptionToken(sponsorship.Id, sponsorshipType)); } catch { diff --git a/src/Core/Services/NoopImplementations/NoopMailService.cs b/src/Core/Services/NoopImplementations/NoopMailService.cs index 7a648a447..f32e9d96a 100644 --- a/src/Core/Services/NoopImplementations/NoopMailService.cs +++ b/src/Core/Services/NoopImplementations/NoopMailService.cs @@ -201,17 +201,12 @@ namespace Bit.Core.Services return Task.FromResult(0); } - public Task SendFamiliesForEnterpriseInviteRedeemableEmailAsync(string email, string organizationName, string token) + public Task SendFamiliesForEnterpriseOfferEmailAsync(string email, string organizationName, string token) { return Task.FromResult(0); } - public Task SendFamiliesForEnterpriseInviteRedeemedToFamilyUserEmailAsync(string email) - { - return Task.FromResult(0); - } - - public Task SendFamiliesForEnterpriseInviteRedeemedToOrgUserEmailAsync(string email, string organizationName) + public Task SendFamiliesForEnterpriseRedeemedEmailsAsync(string familyUserEmail, string sponsorEmail, string sponsorOrgName) { return Task.FromResult(0); } diff --git a/test/Core.Test/Services/OrganizationSponsorshipServiceTests.cs b/test/Core.Test/Services/OrganizationSponsorshipServiceTests.cs index 2b0af9b7c..87914910f 100644 --- a/test/Core.Test/Services/OrganizationSponsorshipServiceTests.cs +++ b/test/Core.Test/Services/OrganizationSponsorshipServiceTests.cs @@ -8,9 +8,11 @@ using Bit.Core.Services; using Bit.Test.Common.AutoFixture; using Bit.Test.Common.AutoFixture.Attributes; using Bit.Test.Common.Helpers; +using Microsoft.AspNetCore.DataProtection; using Microsoft.IdentityModel.Tokens; using NSubstitute; using NSubstitute.ExceptionExtensions; +using NSubstitute.Extensions; using Xunit; namespace Bit.Core.Test.Services @@ -34,13 +36,24 @@ namespace Bit.Core.Test.Services [Theory] [BitAutoData] public async Task OfferSponsorship_CreatesSponsorship(Organization sponsoringOrg, OrganizationUser sponsoringOrgUser, - string sponsoredEmail, string friendlyName, SutProvider sutProvider) + string sponsoredEmail, string friendlyName, Guid sponsorshipId, + SutProvider sutProvider) { + var dataProtector = Substitute.For(); + sutProvider.GetDependency().CreateProtector(default).ReturnsForAnyArgs(dataProtector); + sutProvider.GetDependency().CreateAsync(default).ReturnsForAnyArgs(callInfo => + { + var sponsorship = callInfo.Arg(); + sponsorship.Id = sponsorshipId; + return sponsorship; + }); + await sutProvider.Sut.OfferSponsorshipAsync(sponsoringOrg, sponsoringOrgUser, PlanSponsorshipType.FamiliesForEnterprise, sponsoredEmail, friendlyName); var expectedSponsorship = new OrganizationSponsorship { + Id = sponsorshipId, SponsoringOrganizationId = sponsoringOrg.Id, SponsoringOrganizationUserId = sponsoringOrgUser.Id, FriendlyName = friendlyName, @@ -51,7 +64,10 @@ namespace Bit.Core.Test.Services await sutProvider.GetDependency().Received(1) .CreateAsync(Arg.Is(s => sponsorshipValidator(s, expectedSponsorship))); - // TODO: Validate email called with appropriate token.s + + await sutProvider.GetDependency().Received(1). + SendFamiliesForEnterpriseOfferEmailAsync(sponsoredEmail, sponsoringOrg.Name, + Arg.Any()); } [Theory]