mirror of
https://github.com/bitwarden/server
synced 2026-01-03 17:14:00 +00:00
[PM-21741] Welcome email updates (#6479)
feat(PM-21741): implement MJML welcome email templates with feature flag support - Add MJML templates for individual, family, and organization welcome emails - Track *.hbs artifacts from MJML build - Implement feature flag for gradual rollout of new email templates - Update RegisterUserCommand and HandlebarsMailService to support new templates - Add text versions and sanitization for all welcome emails - Fetch organization data from database for welcome emails - Add comprehensive test coverage for registration flow Co-authored-by: Rui Tomé <108268980+r-tome@users.noreply.github.com>
This commit is contained in:
@@ -268,4 +268,115 @@ public class HandlebarsMailServiceTests
|
||||
// Assert
|
||||
await _mailDeliveryService.Received(1).SendEmailAsync(Arg.Any<MailMessage>());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SendIndividualUserWelcomeEmailAsync_SendsCorrectEmail()
|
||||
{
|
||||
// Arrange
|
||||
var user = new User
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
Email = "test@example.com"
|
||||
};
|
||||
|
||||
// Act
|
||||
await _sut.SendIndividualUserWelcomeEmailAsync(user);
|
||||
|
||||
// Assert
|
||||
await _mailDeliveryService.Received(1).SendEmailAsync(Arg.Is<MailMessage>(m =>
|
||||
m.MetaData != null &&
|
||||
m.ToEmails.Contains("test@example.com") &&
|
||||
m.Subject == "Welcome to Bitwarden!" &&
|
||||
m.Category == "Welcome"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SendOrganizationUserWelcomeEmailAsync_SendsCorrectEmailWithOrganizationName()
|
||||
{
|
||||
// Arrange
|
||||
var user = new User
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
Email = "user@company.com"
|
||||
};
|
||||
var organizationName = "Bitwarden Corp";
|
||||
|
||||
// Act
|
||||
await _sut.SendOrganizationUserWelcomeEmailAsync(user, organizationName);
|
||||
|
||||
// Assert
|
||||
await _mailDeliveryService.Received(1).SendEmailAsync(Arg.Is<MailMessage>(m =>
|
||||
m.MetaData != null &&
|
||||
m.ToEmails.Contains("user@company.com") &&
|
||||
m.Subject == "Welcome to Bitwarden!" &&
|
||||
m.HtmlContent.Contains("Bitwarden Corp") &&
|
||||
m.Category == "Welcome"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SendFreeOrgOrFamilyOrgUserWelcomeEmailAsync_SendsCorrectEmailWithFamilyTemplate()
|
||||
{
|
||||
// Arrange
|
||||
var user = new User
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
Email = "family@example.com"
|
||||
};
|
||||
var familyOrganizationName = "Smith Family";
|
||||
|
||||
// Act
|
||||
await _sut.SendFreeOrgOrFamilyOrgUserWelcomeEmailAsync(user, familyOrganizationName);
|
||||
|
||||
// Assert
|
||||
await _mailDeliveryService.Received(1).SendEmailAsync(Arg.Is<MailMessage>(m =>
|
||||
m.MetaData != null &&
|
||||
m.ToEmails.Contains("family@example.com") &&
|
||||
m.Subject == "Welcome to Bitwarden!" &&
|
||||
m.HtmlContent.Contains("Smith Family") &&
|
||||
m.Category == "Welcome"));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("Acme Corp", "Acme Corp")]
|
||||
[InlineData("Company & Associates", "Company & Associates")]
|
||||
[InlineData("Test \"Quoted\" Org", "Test "Quoted" Org")]
|
||||
public async Task SendOrganizationUserWelcomeEmailAsync_SanitizesOrganizationNameForEmail(string inputOrgName, string expectedSanitized)
|
||||
{
|
||||
// Arrange
|
||||
var user = new User
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
Email = "test@example.com"
|
||||
};
|
||||
|
||||
// Act
|
||||
await _sut.SendOrganizationUserWelcomeEmailAsync(user, inputOrgName);
|
||||
|
||||
// Assert
|
||||
await _mailDeliveryService.Received(1).SendEmailAsync(Arg.Is<MailMessage>(m =>
|
||||
m.HtmlContent.Contains(expectedSanitized) &&
|
||||
!m.HtmlContent.Contains("<script>") && // Ensure script tags are removed
|
||||
m.Category == "Welcome"));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("test@example.com")]
|
||||
[InlineData("user+tag@domain.co.uk")]
|
||||
[InlineData("admin@organization.org")]
|
||||
public async Task SendIndividualUserWelcomeEmailAsync_HandlesVariousEmailFormats(string email)
|
||||
{
|
||||
// Arrange
|
||||
var user = new User
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
Email = email
|
||||
};
|
||||
|
||||
// Act
|
||||
await _sut.SendIndividualUserWelcomeEmailAsync(user);
|
||||
|
||||
// Assert
|
||||
await _mailDeliveryService.Received(1).SendEmailAsync(Arg.Is<MailMessage>(m =>
|
||||
m.ToEmails.Contains(email)));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user