Skip to content

Commit

Permalink
Merge pull request #302 from DFE-Digital/113209-fam-invite-a-contributor
Browse files Browse the repository at this point in the history
Refactored email service and added join a mat templating
  • Loading branch information
jarednimble authored Jan 19, 2023
2 parents 444ab0a + a83899a commit 3051588
Show file tree
Hide file tree
Showing 22 changed files with 313 additions and 75 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using AutoFixture;
using AutoFixture.AutoMoq;
using AutoFixture.Kernel;

namespace Dfe.Academies.External.Web.UnitTest;

public class AutoPopulatedMoqPropertiesCustomization : ICustomization
{
public void Customize(IFixture fixture)
{
fixture.Customizations.Add(
new PropertiesPostprocessor(
new MockPostprocessor(
new MethodInvoker(
new MockConstructorQuery()))));
fixture.ResidueCollectors.Add(new MockRelay());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using System.Collections.Generic;
using System.Reflection;
using AutoFixture;
using AutoMapper;
using AutoMapper.Internal;
using Dfe.Academies.External.Web.AutoMapper;
using Dfe.Academies.External.Web.Dtos;
using Dfe.Academies.External.Web.Models.EmailTemplates;
using FluentAssertions;
using NUnit.Framework;

namespace Dfe.Academies.External.Web.UnitTest.Automapper
{
public class AutoMapperSetupTests
{
private Fixture _fixture = new Fixture();
private IMapper _mapper;
public AutoMapperSetupTests()
{
_fixture.Customize(new AutoPopulatedMoqPropertiesCustomization());

var mapperConfig = new MapperConfiguration(cfg =>
{
cfg.AddProfile<AutoMapperProfile>();
});

mapperConfig.AssertConfigurationIsValid();
_mapper = new Mapper(mapperConfig);
}

[Test]
public void Map_WhenGivenEmailVariablesDto_ReturnsDictionary()
{
var emailTemplate = _fixture.Create<EmailVariablesDto>();
var result = _mapper.Map<IDictionary<string, dynamic>>(emailTemplate);
foreach (var propertyInfo in emailTemplate.GetType().GetProperties())
{
var value = propertyInfo.GetValue(emailTemplate, null);
result.Values.Should().Contain(value);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@

<ItemGroup>
<PackageReference Include="AutoFixture" Version="4.17.0" />
<PackageReference Include="AutoFixture.AutoMoq" Version="4.17.0" />
<PackageReference Include="Bogus" Version="34.0.2" />
<PackageReference Include="FluentAssertions" Version="6.9.0" />
<PackageReference Include="FluentValidation" Version="11.2.2" />
<PackageReference Include="IdGen" Version="3.0.1" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.1" />
Expand Down
23 changes: 23 additions & 0 deletions Dfe.Academies.External.Web.UnitTest/PropertiesPostprocessor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using AutoFixture.Kernel;

namespace Dfe.Academies.External.Web.UnitTest;

public class PropertiesPostprocessor : ISpecimenBuilder
{
private readonly ISpecimenBuilder builder;

public PropertiesPostprocessor(ISpecimenBuilder builder)
{
this.builder = builder;
}

public object Create(object request, ISpecimenContext context)
{
dynamic s = this.builder.Create(request, context);
if (s is NoSpecimen)
return s;

s.SetupAllProperties();
return s;
}
}
8 changes: 8 additions & 0 deletions Dfe.Academies.External.Web/AutoMapper/AutoMapperProfile.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using AutoMapper;

namespace Dfe.Academies.External.Web.AutoMapper;

public class AutoMapperProfile : Profile
{
public AutoMapperProfile() => AutoMapperSetup.AddMappings(this);
}
18 changes: 18 additions & 0 deletions Dfe.Academies.External.Web/AutoMapper/AutoMapperSetup.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using AutoMapper;
using Dfe.Academies.External.Web.Dtos;

namespace Dfe.Academies.External.Web.AutoMapper;

public static class AutoMapperSetup
{
public static void AddMappings(Profile profile)
{
profile.CreateMap<EmailVariablesDto, Dictionary<string, dynamic>>()
.ConvertUsing(x => new Dictionary<string, dynamic>
{
{"invitee_name", x.ContributorName},
{"school", x.SchoolName},
{"inviting_contributor", x.InvitingUsername}
});
}
}
2 changes: 2 additions & 0 deletions Dfe.Academies.External.Web/Dfe.Academies.External.Web.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="AutoMapper" Version="12.0.1" />
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.0" />
<PackageReference Include="FluentValidation" Version="11.2.2" />
<PackageReference Include="GovUk.Frontend.AspNetCore" Version="0.5.1" />
<PackageReference Include="GovukNotify" Version="6.1.0" />
Expand Down
8 changes: 8 additions & 0 deletions Dfe.Academies.External.Web/Dtos/EmailVariablesDto.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Dfe.Academies.External.Web.Dtos;

public record EmailVariablesDto
{
public string ContributorName { get; set; }
public string SchoolName { get; set; }
public string InvitingUsername { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using Dfe.Academies.External.Web.Enums;
using Dfe.Academies.External.Web.Models.EmailTemplates;

namespace Dfe.Academies.External.Web.Factories;

public class ContributorNotifyTemplateFactory : IContributorNotifyTemplateFactory
{
private readonly List<IContributorTemplate> _emailTemplates;

public ContributorNotifyTemplateFactory(IEnumerable<IContributorTemplate> emailTemplates)
{
_emailTemplates = emailTemplates.ToList();
}
public IContributorTemplate Get(ApplicationTypes applicationType, SchoolRoles schoolRole)
{
return _emailTemplates.First(x =>
x.ApplicationType == applicationType && x.SchoolRole == schoolRole);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Dfe.Academies.External.Web.Enums;
using Dfe.Academies.External.Web.Models.EmailTemplates;

namespace Dfe.Academies.External.Web.Factories
{
public interface IContributorNotifyTemplateFactory
{
IContributorTemplate Get(ApplicationTypes applicationType, SchoolRoles schoolRole);
}
}
10 changes: 10 additions & 0 deletions Dfe.Academies.External.Web/Helpers/NotifyTemplateSettings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace Dfe.Academies.External.Web.Helpers
{
public class NotifyTemplateSettings
{
public string JamChairTemplateId { get; set; }
public string JamNonChairTemplateId { get; set; }
public string FamChairTemplateId { get; set; }
public string FamNonChairTemplateId { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System.Dynamic;
using Dfe.Academies.External.Web.Enums;
using Dfe.Academies.External.Web.Helpers;
using Microsoft.Extensions.Options;

namespace Dfe.Academies.External.Web.Models.EmailTemplates
{
public class FormAMatChairContributor : IContributorTemplate
{
public ApplicationTypes ApplicationType => ApplicationTypes.FormAMat;
public SchoolRoles SchoolRole => SchoolRoles.ChairOfGovernors;
public string TemplateId { get; }

public FormAMatChairContributor(IOptions<NotifyTemplateSettings> notifyTemplateSettings)
{
TemplateId = notifyTemplateSettings.Value.FamChairTemplateId;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using Dfe.Academies.External.Web.Enums;
using Dfe.Academies.External.Web.Helpers;
using Microsoft.Extensions.Options;

namespace Dfe.Academies.External.Web.Models.EmailTemplates
{
public class FormAMatNonChairContributor : IContributorTemplate
{
public ApplicationTypes ApplicationType => ApplicationTypes.FormAMat;
public SchoolRoles SchoolRole => SchoolRoles.Other;
public string TemplateId { get; }

public FormAMatNonChairContributor(IOptions<NotifyTemplateSettings> notifyTemplateSettings)
{
TemplateId = notifyTemplateSettings.Value.FamNonChairTemplateId;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Dfe.Academies.External.Web.Enums;

namespace Dfe.Academies.External.Web.Models.EmailTemplates
{
public interface IContributorTemplate : IEmailTemplate
{
public SchoolRoles SchoolRole { get; }
public ApplicationTypes ApplicationType { get; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Dfe.Academies.External.Web.Models.EmailTemplates;

public interface IEmailTemplate
{
public string TemplateId { get; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System.Dynamic;
using Dfe.Academies.External.Web.Enums;
using Dfe.Academies.External.Web.Helpers;
using Microsoft.Extensions.Options;

namespace Dfe.Academies.External.Web.Models.EmailTemplates
{
public class JoinAMatChairContributor : IContributorTemplate
{
public ApplicationTypes ApplicationType => ApplicationTypes.JoinAMat;
public SchoolRoles SchoolRole => SchoolRoles.ChairOfGovernors;
public string TemplateId { get; }

public JoinAMatChairContributor(IOptions<NotifyTemplateSettings> notifyTemplateSettings)
{
TemplateId = notifyTemplateSettings.Value.JamChairTemplateId;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System.Dynamic;
using Dfe.Academies.External.Web.Enums;
using Dfe.Academies.External.Web.Helpers;
using Microsoft.Extensions.Options;

namespace Dfe.Academies.External.Web.Models.EmailTemplates
{
public class JoinAMatNonChairContributor : IContributorTemplate
{
public ApplicationTypes ApplicationType => ApplicationTypes.JoinAMat;
public SchoolRoles SchoolRole => SchoolRoles.Other;
public string TemplateId { get; }

public JoinAMatNonChairContributor(IOptions<NotifyTemplateSettings> notifyTemplateSettings)
{
TemplateId = notifyTemplateSettings.Value.JamNonChairTemplateId;
}
}
}
12 changes: 9 additions & 3 deletions Dfe.Academies.External.Web/Pages/AddAContributor.cshtml.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System.ComponentModel.DataAnnotations;
using System.Dynamic;
using System.Security.Claims;
using Dfe.Academies.External.Web.Attributes;
using Dfe.Academies.External.Web.Dtos;
using Dfe.Academies.External.Web.Enums;
using Dfe.Academies.External.Web.Models;
using Dfe.Academies.External.Web.Pages.Base;
Expand Down Expand Up @@ -119,10 +121,14 @@ public async Task<IActionResult> OnPostAsync()
string firstName = User.FindFirst(ClaimTypes.GivenName)?.Value ?? "";
string lastName = User.FindFirst(ClaimTypes.Surname)?.Value ?? "";
string invitingUserName = $"{firstName} {lastName}";

var schoolName = ApplicationSchoolName(draftConversionApplication);
var emailVariables = new EmailVariablesDto
{
ContributorName = Name!, InvitingUsername = invitingUserName, SchoolName = schoolName
};

await _contributorEmailSenderService.SendInvitationToContributor(draftConversionApplication.ApplicationType, ContributorRole,
Name!, EmailAddress!, ApplicationSchoolName(draftConversionApplication),
invitingUserName);
EmailAddress!, emailVariables);

// update temp store for next step
draftConversionApplication.Contributors.Add(contributor);
Expand Down
14 changes: 14 additions & 0 deletions Dfe.Academies.External.Web/Program.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
using System.Globalization;
using Dfe.Academies.External.Web.AutoMapper;
using Dfe.Academies.External.Web.Extensions;
using Dfe.Academies.External.Web.Factories;
using Dfe.Academies.External.Web.Helpers;
using Dfe.Academies.External.Web.Middleware;
using Dfe.Academies.External.Web.Models.EmailTemplates;
using Dfe.Academies.External.Web.Routing;
using Dfe.Academies.External.Web.Services;
using GovUk.Frontend.AspNetCore;
Expand All @@ -10,6 +13,9 @@
using Microsoft.AspNetCore.Localization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ApplicationModels;
using Microsoft.Extensions.Options;
using Notify.Client;
using Notify.Interfaces;
using Polly;
using Polly.Extensions.Http;

Expand Down Expand Up @@ -136,6 +142,14 @@
);
builder.Services.AddSingleton<IAadAuthorisationHelper, AadAuthorisationHelper>();

builder.Services.AddAutoMapper(typeof(AutoMapperProfile));
builder.Services.AddTransient<IAsyncNotificationClient, NotificationClient>(x => new NotificationClient(builder.Configuration["emailnotifications:key"]));
builder.Services.Configure<NotifyTemplateSettings>(builder.Configuration.GetSection("govuk-notify-templates"));
builder.Services.AddSingleton<IContributorTemplate, FormAMatChairContributor>(x => new FormAMatChairContributor(x.GetRequiredService<IOptions<NotifyTemplateSettings>>()));
builder.Services.AddSingleton<IContributorTemplate, FormAMatNonChairContributor>(x => new FormAMatNonChairContributor(x.GetRequiredService<IOptions<NotifyTemplateSettings>>()));
builder.Services.AddSingleton<IContributorTemplate, JoinAMatChairContributor>(x => new JoinAMatChairContributor(x.GetRequiredService<IOptions<NotifyTemplateSettings>>()));
builder.Services.AddSingleton<IContributorTemplate, JoinAMatNonChairContributor>(x => new JoinAMatNonChairContributor(x.GetRequiredService<IOptions<NotifyTemplateSettings>>()));
builder.Services.AddSingleton<IContributorNotifyTemplateFactory, ContributorNotifyTemplateFactory>();
builder.Services.AddHttpClient<IFileUploadService, FileUploadService>(client =>
{
client.BaseAddress = new Uri(configuration["Sharepoint:ApiUrl"]);
Expand Down
Loading

0 comments on commit 3051588

Please sign in to comment.