Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial integration of Charity Commission API. #940

Merged
merged 6 commits into from
Nov 22, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
using CO.CDP.OrganisationApp.CharityCommission;
using CO.CDP.OrganisationApp.Constants;
using CO.CDP.OrganisationApp.Models;
using CO.CDP.OrganisationApp.Pages.Registration;
using CO.CDP.OrganisationApp.ThirdPartyApiClients.CharityCommission;
using FluentAssertions;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
Expand All @@ -13,10 +16,12 @@ namespace CO.CDP.OrganisationApp.Tests.Pages.Registration;
public class OrganisationEmailModelTest
{
private readonly Mock<ISession> sessionMock;
private readonly Mock<ICharityCommissionApi> charityCommissionMock;

public OrganisationEmailModelTest()
{
sessionMock = new Mock<ISession>();
charityCommissionMock = new Mock<ICharityCommissionApi>();
sessionMock.Setup(session => session.Get<UserDetails>(Session.UserDetailsKey))
.Returns(new UserDetails { UserUrn = "urn:test" });
}
Expand Down Expand Up @@ -143,20 +148,66 @@ public void OnPost_WhenModelStateIsValidAndRedirectToSummary_ShouldRedirectToOrg
.Which.PageName.Should().Be("OrganisationDetailsSummary");
}

private RegistrationDetails DummyRegistrationDetails()
[Fact]
public async Task OnGet_WhenCharityCommissionNumberProvided_ShouldPrepopulateEmail()
{
var registrationDetails = DummyRegistrationDetails(organisationName: "",
scheme: OrganisationSchemeType.CharityCommissionEnglandWales,
organisationEmailAddress: "");
sessionMock.Setup(s => s.Get<RegistrationDetails>(Session.RegistrationDetailsKey)).Returns(registrationDetails);

var chartiyDetails = GivenEmailOnCharitiesCommission();
var model = GivenOrganisationEmailModel();

charityCommissionMock.Setup(s => s.GetCharityDetails(registrationDetails.OrganisationIdentificationNumber!))
.ReturnsAsync(chartiyDetails);

await model.OnGet();

model.EmailAddress.Should().Be(chartiyDetails.Email);
}

[Fact]
public async Task OnGet_WhenCharityCommissionNumberProvidedRegDetailsProvided_ShouldNotPrepopulateEmail()
{
var registrationDetails = DummyRegistrationDetails(scheme: OrganisationSchemeType.CharityCommissionEnglandWales);
sessionMock.Setup(s => s.Get<RegistrationDetails>(Session.RegistrationDetailsKey)).Returns(registrationDetails);

var chartiyDetails = GivenEmailOnCharitiesCommission();
var model = GivenOrganisationEmailModel();

charityCommissionMock.Setup(s => s.GetCharityDetails(registrationDetails.OrganisationIdentificationNumber!))
.ReturnsAsync(chartiyDetails);

await model.OnGet();

model.EmailAddress.Should().Be(registrationDetails.OrganisationEmailAddress);
}

private CharityDetails GivenEmailOnCharitiesCommission()
{
return new CharityDetails()
{
Email = "contactus@britishredcross.org"
};
}

private RegistrationDetails DummyRegistrationDetails(string organisationName = "TestOrg",
string scheme = "TestType",
string organisationEmailAddress = "test@example.com")
{
var registrationDetails = new RegistrationDetails
{
OrganisationName = "TestOrg",
OrganisationScheme = "TestType",
OrganisationEmailAddress = "test@example.com"
OrganisationName = organisationName,
OrganisationScheme = scheme,
OrganisationEmailAddress = organisationEmailAddress
};

return registrationDetails;
}

private OrganisationEmailModel GivenOrganisationEmailModel()
{
return new OrganisationEmailModel(sessionMock.Object);
return new OrganisationEmailModel(sessionMock.Object, charityCommissionMock.Object);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
using CO.CDP.OrganisationApp.CharityCommission;
using CO.CDP.OrganisationApp.Constants;
using CO.CDP.OrganisationApp.Models;
using CO.CDP.OrganisationApp.Pages.Registration;
using CO.CDP.OrganisationApp.ThirdPartyApiClients;
using CO.CDP.OrganisationApp.ThirdPartyApiClients.CharityCommission;
using CO.CDP.OrganisationApp.ThirdPartyApiClients.CompaniesHouse;
using FluentAssertions;
using Microsoft.AspNetCore.Http;
Expand All @@ -16,11 +19,13 @@ public class OrganisationNameModelTest
{
private readonly Mock<ISession> sessionMock;
private readonly Mock<ICompaniesHouseApi> companiesHouseMock;
private readonly Mock<ICharityCommissionApi> charityCommissionMock;

public OrganisationNameModelTest()
{
sessionMock = new Mock<ISession>();
companiesHouseMock = new Mock<ICompaniesHouseApi>();
charityCommissionMock = new Mock<ICharityCommissionApi>();
sessionMock.Setup(session => session.Get<UserDetails>(Session.UserDetailsKey))
.Returns(new UserDetails { UserUrn = "urn:test" });
}
Expand Down Expand Up @@ -140,6 +145,40 @@ public async Task OnGet_WhenCompaniesHouseNumberAndCompanyNameProvided_ShouldNot
model.OrganisationName.Should().Be(registrationDetails.OrganisationName);
}

[Fact]
public async Task OnGet_WhenCharityCommissionNumberProvided_ShouldPrepopulateCompanyName()
{
var registrationDetails = DummyRegistrationDetails(organisationName: "", scheme: OrganisationSchemeType.CharityCommissionEnglandWales);
sessionMock.Setup(s => s.Get<RegistrationDetails>(Session.RegistrationDetailsKey)).Returns(registrationDetails);

var chartiyDetails = GivenNameOnCharitiesCommission(organisationName: "British Red Cross");
var model = GivenOrganisationNameModel();

charityCommissionMock.Setup(s => s.GetCharityDetails(registrationDetails.OrganisationIdentificationNumber!))
.ReturnsAsync(chartiyDetails);

await model.OnGet();

model.OrganisationName.Should().Be(chartiyDetails.Name);
}

[Fact]
public async Task OnGet_WhenCharityCommissionNumberProvidedAndRegDetailsProvided_ShouldNotPrepopulateCompanyName()
{
var registrationDetails = DummyRegistrationDetails(organisationName: "British Heart Foundation", scheme: OrganisationSchemeType.CharityCommissionEnglandWales);
sessionMock.Setup(s => s.Get<RegistrationDetails>(Session.RegistrationDetailsKey)).Returns(registrationDetails);

var chartiyDetails = GivenNameOnCharitiesCommission(organisationName: "British Red Cross");
var model = GivenOrganisationNameModel();

charityCommissionMock.Setup(s => s.GetCharityDetails(registrationDetails.OrganisationIdentificationNumber!))
.ReturnsAsync(chartiyDetails);

await model.OnGet();

model.OrganisationName.Should().Be(registrationDetails.OrganisationName);
}

[Fact]
public void OnPost_WhenValidModel_ShouldRedirectToOrganisationEmailPage()
{
Expand Down Expand Up @@ -169,15 +208,15 @@ public void OnPost_WhenModelStateIsValidAndRedirectToSummary_ShouldRedirectToOrg
.Which.PageName.Should().Be("OrganisationDetailsSummary");
}

private RegistrationDetails DummyRegistrationDetails(string organisationName = "TestOrg")
private RegistrationDetails DummyRegistrationDetails(string organisationName = "TestOrg", string scheme = "")
{
var registrationDetails = new RegistrationDetails
{
OrganisationName = "TestOrg",
OrganisationScheme = "TestType",
OrganisationName = organisationName,
OrganisationScheme = scheme,
OrganisationEmailAddress = "test@example.com",
OrganisationIdentificationNumber = "123456",
OrganisationHasCompaniesHouseNumber = true,
OrganisationHasCompaniesHouseNumber = true
};

return registrationDetails;
Expand All @@ -188,6 +227,14 @@ private CompanyProfile GivenProfileOnCompaniesHouse(string organisationName = ""
return new CompanyProfile() { CompanyName = organisationName };
}

private CharityDetails GivenNameOnCharitiesCommission(string organisationName = "")
{
return new CharityDetails()
{
Name = organisationName
};
}

private RegisteredAddress GivenRegisteredAddressOnCompaniesHouse()
{
return new RegisteredAddress()
Expand All @@ -202,6 +249,6 @@ private RegisteredAddress GivenRegisteredAddressOnCompaniesHouse()

private OrganisationNameModel GivenOrganisationNameModel()
{
return new OrganisationNameModel(sessionMock.Object, companiesHouseMock.Object);
return new OrganisationNameModel(sessionMock.Object, charityCommissionMock.Object, companiesHouseMock.Object);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
using CO.CDP.OrganisationApp.CharityCommission;
using CO.CDP.OrganisationApp.Constants;
using CO.CDP.OrganisationApp.Models;
using CO.CDP.OrganisationApp.Pages.Registration;
using CO.CDP.OrganisationApp.ThirdPartyApiClients;
using CO.CDP.OrganisationApp.ThirdPartyApiClients.CharityCommission;
using CO.CDP.OrganisationApp.ThirdPartyApiClients.CompaniesHouse;
using FluentAssertions;
using Microsoft.AspNetCore.Http;
Expand All @@ -17,11 +19,13 @@ public class OrganisationRegisteredAddressModelTest
{
private readonly Mock<ISession> sessionMock;
private readonly Mock<ICompaniesHouseApi> companiesHouseMock;
private readonly Mock<ICharityCommissionApi> charityCommissionMock;

public OrganisationRegisteredAddressModelTest()
{
sessionMock = new Mock<ISession>();
companiesHouseMock = new Mock<ICompaniesHouseApi>();
charityCommissionMock = new Mock<ICharityCommissionApi>();
sessionMock.Setup(session => session.Get<UserDetails>(Session.UserDetailsKey))
.Returns(new UserDetails { UserUrn = "urn:test" });
}
Expand Down Expand Up @@ -184,7 +188,46 @@ public async Task OnGet_ValidSession_ReturnsRegistrationDetails()
model.Address.AddressLine1.Should().Be(registrationDetails.OrganisationAddressLine1);
model.Address.TownOrCity.Should().Be(registrationDetails.OrganisationCityOrTown);
model.Address.Postcode.Should().Be(registrationDetails.OrganisationPostcode);
//model.Country.Should().Be(registrationDetails.OrganisationCountry);
}

[Fact]
public async Task OnGet_WhenCharityCommissionNumberProvided_ShouldPrepopulateRegisteredAddress()
{
RegistrationDetails registrationDetails = DummyRegistrationDetails(emptyAddress: true,
scheme: OrganisationSchemeType.CharityCommissionEnglandWales, hasCompaniesHouseNumber: false);
sessionMock.Setup(s => s.Get<RegistrationDetails>(Session.RegistrationDetailsKey)).Returns(registrationDetails);

var model = GivenOrganisationAddressModel();
var chartiyDetails = GivenRegisteredAddressOnCharitiesCommission();

charityCommissionMock.Setup(s => s.GetCharityDetails(registrationDetails.OrganisationIdentificationNumber!))
.ReturnsAsync(chartiyDetails);

await model.OnGet();

model.Address.AddressLine1.Should().Be(chartiyDetails.AddressLine2);
model.Address.TownOrCity.Should().Be(chartiyDetails.AddressLine3);
model.Address.Postcode.Should().Be(chartiyDetails.PostalCode);
}

[Fact]
public async Task OnGet_WhenCharityCommissionNumberAndRegDetailsProvided_ShouldNotPrepopulateRegisteredAddress()
{
RegistrationDetails registrationDetails = DummyRegistrationDetails(scheme: OrganisationSchemeType.CharityCommissionEnglandWales,
hasCompaniesHouseNumber: false);
sessionMock.Setup(s => s.Get<RegistrationDetails>(Session.RegistrationDetailsKey)).Returns(registrationDetails);

var model = GivenOrganisationAddressModel();
var chartiyDetails = GivenRegisteredAddressOnCharitiesCommission();

charityCommissionMock.Setup(s => s.GetCharityDetails(registrationDetails.OrganisationIdentificationNumber!))
.ReturnsAsync(chartiyDetails);

await model.OnGet();

model.Address.AddressLine1.Should().Be(registrationDetails.OrganisationAddressLine1);
model.Address.TownOrCity.Should().Be(registrationDetails.OrganisationCityOrTown);
model.Address.Postcode.Should().Be(registrationDetails.OrganisationPostcode);
}

[Fact]
Expand Down Expand Up @@ -225,7 +268,7 @@ public async Task OnGet_WhenCompaniesHouseNumberAndRegDetailsProvided_ShouldNotP
model.Address.Postcode.Should().Be(registrationDetails.OrganisationPostcode);
}

private RegistrationDetails DummyRegistrationDetails(bool emptyAddress = false)
private RegistrationDetails DummyRegistrationDetails(bool emptyAddress = false, string scheme = "", bool hasCompaniesHouseNumber = true)
{
var registrationDetails = new RegistrationDetails
{
Expand All @@ -235,7 +278,8 @@ private RegistrationDetails DummyRegistrationDetails(bool emptyAddress = false)
OrganisationIdentificationNumber = "123456",
OrganisationHasCompaniesHouseNumber = true,
OrganisationCountryName = "United Kingdom",
OrganisationCountryCode = "GB"
OrganisationCountryCode = "GB",
OrganisationScheme = scheme
};

return registrationDetails;
Expand All @@ -253,8 +297,18 @@ private RegisteredAddress GivenRegisteredAddressOnCompaniesHouse()
};
}

private CharityDetails GivenRegisteredAddressOnCharitiesCommission()
{
return new CharityDetails()
{
AddressLine1 = "1 Mayfair",
AddressLine2 = "",
PostalCode = "SW2 1PT"
};
}

private OrganisationRegisteredAddressModel GivenOrganisationAddressModel()
{
return new OrganisationRegisteredAddressModel(sessionMock.Object, companiesHouseMock.Object) { Address = new() };
return new OrganisationRegisteredAddressModel(sessionMock.Object, charityCommissionMock.Object, companiesHouseMock.Object) { Address = new() };
}
}
1 change: 1 addition & 0 deletions Frontend/CO.CDP.OrganisationApp/Logging/CdpErrorCodes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ namespace CO.CDP.OrganisationApp.Logging;
public class CdpErrorCodes
{
public const string CompaniesHouseApiError = "CDP_COMPANIES_HOUSE_API_ERROR";
public const string CharityCommissionApiError = "CDP_CHARITY_COMMISSION_API_ERROR";
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
using CO.CDP.OrganisationApp.Constants;
using CO.CDP.OrganisationApp.Models;
using CO.CDP.OrganisationApp.ThirdPartyApiClients.CharityCommission;
using Microsoft.AspNetCore.Mvc;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;

namespace CO.CDP.OrganisationApp.Pages.Registration;

[ValidateRegistrationStep]
public class OrganisationEmailModel(ISession session) : RegistrationStepModel(session)
public class OrganisationEmailModel(ISession session, ICharityCommissionApi charityCommissionApi) : RegistrationStepModel(session)
{
public override string CurrentPage => OrganisationEmailPage;

Expand All @@ -19,9 +21,19 @@ public class OrganisationEmailModel(ISession session) : RegistrationStepModel(se
[BindProperty]
public bool? RedirectToSummary { get; set; }

public void OnGet()
public async Task OnGet()
{
EmailAddress = RegistrationDetails.OrganisationEmailAddress;

if ((RegistrationDetails.OrganisationScheme == OrganisationSchemeType.CharityCommissionEnglandWales) && (string.IsNullOrEmpty(EmailAddress)))
{
var details = await charityCommissionApi.GetCharityDetails(RegistrationDetails.OrganisationIdentificationNumber!);
Copy link
Member

@jakzal jakzal Nov 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than causing a potential runtime exception with !, can we move the check to the condition above to ensure RegistrationDetails.OrganisationIdentificationNumber != null please?

This will make ! redundant. Noticed the same thing in other places.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.


if (details != null)
{
EmailAddress = details.Email;
}
}
}

public IActionResult OnPost()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using CO.CDP.Localization;
using CO.CDP.OrganisationApp.Constants;
using CO.CDP.OrganisationApp.Models;
using CO.CDP.OrganisationApp.ThirdPartyApiClients.CharityCommission;
using CO.CDP.OrganisationApp.ThirdPartyApiClients.CompaniesHouse;
using Microsoft.AspNetCore.Mvc;
using System.ComponentModel;
Expand All @@ -8,7 +10,7 @@
namespace CO.CDP.OrganisationApp.Pages.Registration;

[ValidateRegistrationStep]
public class OrganisationNameModel(ISession session, ICompaniesHouseApi companiesHouseApi) : RegistrationStepModel(session)
public class OrganisationNameModel(ISession session, ICharityCommissionApi charityCommissionApi, ICompaniesHouseApi companiesHouseApi) : RegistrationStepModel(session)
{
public override string CurrentPage => OrganisationNamePage;

Expand All @@ -33,6 +35,16 @@ public async Task OnGet()

OrganisationName = profile != null ? profile.CompanyName ?? string.Empty : string.Empty;
}

if ((RegistrationDetails.OrganisationScheme == OrganisationSchemeType.CharityCommissionEnglandWales) && (string.IsNullOrEmpty(OrganisationName)))
{
var details = await charityCommissionApi.GetCharityDetails(RegistrationDetails.OrganisationIdentificationNumber!);

if (details != null)
{
OrganisationName = details.Name;
}
}
}

public IActionResult OnPost()
Expand Down
Loading