Skip to content

Commit

Permalink
APR-2916 Implemented link to refresh trustees (#941)
Browse files Browse the repository at this point in the history
* APR-2916 code and coverage added

* APR-2916 updated charity outer api calls as response no longer used

* APR-2916 code reworked, but full coverage is pending

* APR-2916 coverage and code updated

* APR-2916 code and coverage complete for rework

* APR-2916 fixed code smells

* APR-2916 removing small code smell from tests

* APR-2916 refresh trustees work moved to new controller

* APR-2916 fine tuning tests

* APR-2916 snagging from technical review complete

* APR-2916 updated tests to use standard naming conventions

* APR-2916 added try catch around charity number retrieval

* APR-2916 added inclusion of main exception into getCharityDetails exception

* APR-2916 removing unneeded empty lines

* APR-2916 added logging around GetCharityDetails and exception

* APR-2916 logging exception

* APR-2916 minor content change

* APR-2916 removing unneeded usings
  • Loading branch information
MarkFCain authored Feb 1, 2022
1 parent c7db9e9 commit 4b0611f
Show file tree
Hide file tree
Showing 23 changed files with 984 additions and 17 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Moq;
using NUnit.Framework;
using SFA.DAS.ApplyService.Application.Organisations.GetOrganisation;
using SFA.DAS.ApplyService.Domain.Entities;
using SFA.DAS.ApplyService.Domain.Interfaces;

namespace SFA.DAS.ApplyService.Application.UnitTests.Handlers.OrganisationHandlerTests
{
[TestFixture]
public class OrganisationHandlerTests
{
private GetOrganisationByApplicationIdHandler _handler;
private Mock<IOrganisationRepository> _repository;
private Guid _applicationId;

[SetUp]
public void TestSetup()
{
_applicationId = Guid.NewGuid();
_repository = new Mock<IOrganisationRepository>();
_handler = new GetOrganisationByApplicationIdHandler(_repository.Object);
}

[Test]
public async Task Handle_ValidRequest_ReturnsOrganisation()
{
var ukprn = 12334455;
var organisation = new Organisation {OrganisationUkprn = ukprn};

_repository.Setup(x => x.GetOrganisationByApplicationId(_applicationId)).ReturnsAsync(organisation);
var result = await _handler.Handle(new GetOrganisationByApplicationIdRequest(_applicationId), new CancellationToken());

Assert.IsNotNull(result);
Assert.AreEqual(result.OrganisationUkprn, ukprn);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Moq;
using NUnit.Framework;
using SFA.DAS.ApplyService.Application.Organisations.UpdateOrganisation;
using SFA.DAS.ApplyService.Domain.Entities;
using SFA.DAS.ApplyService.Domain.Interfaces;
using SFA.DAS.ApplyService.InternalApi.Types.CharityCommission;

namespace SFA.DAS.ApplyService.Application.UnitTests.Handlers.UpdateOrganisationTrusteesHandlerTests
{
[TestFixture]
public class UpdateOrganisationTrusteesHandlerTests
{
private Mock<IOrganisationRepository> _repository;
private UpdateOrganisationTrusteesHandler _handler;
private string _ukprn;
private Guid _updatedBy;

[SetUp]
public void TestSetup()
{
_repository = new Mock<IOrganisationRepository>();
_handler = new UpdateOrganisationTrusteesHandler(_repository.Object);
_ukprn = "12345678";
_updatedBy = Guid.NewGuid();
}

[Test]
public async Task Handle_ValidRequest_ReturnsTrue()
{
var request = new UpdateOrganisationTrusteesRequest
{
Ukprn = _ukprn,
UpdatedBy = _updatedBy,
Trustees = new List<Trustee> { new Trustee { Id = 1, Name = "Cody McCodeface" } }
};

var organisation = new Organisation
{
OrganisationDetails = new OrganisationDetails
{
CharityCommissionDetails = new CharityCommissionDetails()
}
};

_repository.Setup(x => x.GetOrganisationByUkprn(_ukprn)).ReturnsAsync(organisation);

var result = await _handler.Handle(request, new CancellationToken());

Assert.IsTrue(result);
_repository.Verify(x => x.UpdateOrganisation(It.IsAny<Organisation>(),_updatedBy), Times.Once);
}

[Test]
public async Task Handle_OrganisationNotFound_ReturnsFalse()
{
var request = new UpdateOrganisationTrusteesRequest
{
Ukprn = _ukprn,
UpdatedBy = _updatedBy,
Trustees = new List<Trustee> { new Trustee { Id = 1, Name = "Cody McCodeface" } }
};

Organisation organisation = null;

_repository.Setup(x => x.GetOrganisationByUkprn(_ukprn)).ReturnsAsync(organisation);

var result = await _handler.Handle(request, new CancellationToken());

Assert.IsFalse(result);
_repository.Verify(x => x.UpdateOrganisation(It.IsAny<Organisation>(), It.IsAny<Guid>()), Times.Never);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System.Threading;
using System.Threading.Tasks;
using MediatR;
using SFA.DAS.ApplyService.Domain.Entities;
using SFA.DAS.ApplyService.Domain.Interfaces;

namespace SFA.DAS.ApplyService.Application.Organisations.GetOrganisation
{
public class GetOrganisationByApplicationIdHandler : IRequestHandler<GetOrganisationByApplicationIdRequest, Organisation>
{
private readonly IOrganisationRepository _organisationRepository;

public GetOrganisationByApplicationIdHandler(IOrganisationRepository organisationRepository)
{
_organisationRepository = organisationRepository;
}

public async Task<Organisation> Handle(GetOrganisationByApplicationIdRequest request, CancellationToken cancellationToken)
{
return await _organisationRepository.GetOrganisationByApplicationId(request.ApplicationId);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System;
using MediatR;
using SFA.DAS.ApplyService.Domain.Entities;

namespace SFA.DAS.ApplyService.Application.Organisations.GetOrganisation
{
public class GetOrganisationByApplicationIdRequest : IRequest<Organisation>
{
public Guid ApplicationId { get; }
public GetOrganisationByApplicationIdRequest(Guid applicationId)
{
ApplicationId = applicationId;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using MediatR;
using SFA.DAS.ApplyService.Domain.CharityCommission;
using SFA.DAS.ApplyService.Domain.Interfaces;

namespace SFA.DAS.ApplyService.Application.Organisations.UpdateOrganisation
{
public class UpdateOrganisationTrusteesHandler : IRequestHandler<UpdateOrganisationTrusteesRequest, bool>
{
private readonly IOrganisationRepository _organisationRepository;

public UpdateOrganisationTrusteesHandler(IOrganisationRepository organisationRepository)
{
_organisationRepository = organisationRepository;
}

public async Task<bool> Handle(UpdateOrganisationTrusteesRequest request, CancellationToken cancellationToken)
{
var existingOrganisation = await _organisationRepository.GetOrganisationByUkprn(request.Ukprn);
if (existingOrganisation != null)
{
var trustees = request.Trustees.Select(trusteeValue => new Trustee { Name = trusteeValue.Name, Id = trusteeValue.Id.ToString() }).ToList();
existingOrganisation.OrganisationDetails.CharityCommissionDetails.Trustees = trustees;

await _organisationRepository.UpdateOrganisation(existingOrganisation, request.UpdatedBy);

return true;
}

return false;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using MediatR;
using SFA.DAS.ApplyService.InternalApi.Types.CharityCommission;


namespace SFA.DAS.ApplyService.Application.Organisations.UpdateOrganisation
{
public class UpdateOrganisationTrusteesRequest : IRequest<bool>
{
public string Ukprn { get; set; }
public List<Trustee> Trustees { get; set; }
public Guid UpdatedBy { get; set; }
}
}
4 changes: 2 additions & 2 deletions src/SFA.DAS.ApplyService.Data/OrganisationRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ public async Task<Organisation> GetOrganisationByApplicationId(Guid applicationI
var sql =
@"SELECT Organisations.*
FROM Organisations
INNER JOIN Applications ON Applications.ApplyingOrganisationId = Organisations.Id
WHERE Applications.Id = @applicationId";
INNER JOIN Apply ON Apply.OrganisationId = Organisations.Id
WHERE Apply.ApplicationId = @applicationId";

var org = await connection.QuerySingleAsync<Organisation>(sql, new { applicationId });

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace SFA.DAS.ApplyService.Domain.Entities
{
public class RefreshTrusteesResult
{
public bool CharityDetailsNotFound { get; set; }
public string CharityNumber { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using FluentAssertions;
using MediatR;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Moq;
using NUnit.Framework;
using SFA.DAS.ApplyService.Application.Organisations.GetOrganisation;
using SFA.DAS.ApplyService.Domain.Entities;
using SFA.DAS.ApplyService.InternalApi.Controllers;

namespace SFA.DAS.ApplyService.InternalApi.UnitTests.Controllers.OrganisationControllerTests
{
[TestFixture]
public class GetOrganisationByApplicationIdTests
{
private OrganisationController _controller;
private Mock<IMediator> _mediator;
private Mock<ILogger<OrganisationController>> _logger;
private Guid _applicationId = Guid.NewGuid();

[SetUp]
public void TestSetup()
{
_mediator = new Mock<IMediator>();
_logger = new Mock<ILogger<OrganisationController>>();
_controller = new OrganisationController(_mediator.Object, _logger.Object);
}

[Test]
public async Task GetOrganisationByAppicationId_OnSuccess_ReturnsOrganisationAndOk()
{
var organisationId = Guid.NewGuid();
var organisation = new Organisation {Id = organisationId};
_mediator.Setup(x => x.Send(It.IsAny<GetOrganisationByApplicationIdRequest>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(organisation);
var result = await _controller.GetOrganisationByApplicationId(_applicationId);
result.Should().BeOfType<ActionResult<Organisation>>();
result.Result.Should().BeOfType<OkObjectResult>();
var expectedOrganisation =((ObjectResult)result.Result).Value as Organisation;
expectedOrganisation.Id.Should().Be(organisationId);

}

[Test]
public async Task GetOrganisationByAppicationId_NoOrganisationFound_ReturnsNotFound()
{
_mediator.Setup(x => x.Send(It.IsAny<GetOrganisationByApplicationIdRequest>(), It.IsAny<CancellationToken>()))
.ReturnsAsync((Organisation)null);
var result = await _controller.GetOrganisationByApplicationId(_applicationId);
result.Result.Should().BeOfType<NotFoundResult>();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using System.Threading;
using System.Threading.Tasks;
using AutoFixture;
using FluentAssertions;
using MediatR;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Moq;
using NUnit.Framework;
using SFA.DAS.ApplyService.Application.Organisations.UpdateOrganisation;
using SFA.DAS.ApplyService.InternalApi.Controllers;

namespace SFA.DAS.ApplyService.InternalApi.UnitTests.Controllers.OrganisationControllerTests
{
[TestFixture]
public class UpdateOrganisationTrusteeTests
{
private OrganisationController _controller;
private Mock<IMediator> _mediator;
private Mock<ILogger<OrganisationController>> _logger;
private static readonly Fixture AutoFixture = new Fixture();

[SetUp]
public void TestSetup()
{
_mediator = new Mock<IMediator>();
_logger = new Mock<ILogger<OrganisationController>>();
_controller = new OrganisationController(_mediator.Object, _logger.Object);
}

[Test]
public async Task UpdateOrganisationTrustees_OnSuccessfulUpdate_ReturnsOkResponse()
{
var request = AutoFixture.Create<UpdateOrganisationTrusteesRequest>();
_mediator.Setup(x => x.Send(It.IsAny<UpdateOrganisationTrusteesRequest>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
var result = await _controller.UpdateOrganisationTrustees(request);
result.Should().BeOfType<ActionResult<bool>>();
_mediator.Verify(x => x.Send(It.Is<UpdateOrganisationTrusteesRequest>(r=>r.Trustees == request.Trustees && r.Ukprn == request.Ukprn && r.UpdatedBy == request.UpdatedBy), It.IsAny<CancellationToken>()), Times.Once);

result.Result.Should().BeOfType<OkObjectResult>();
}

[Test]
public async Task UpdateOrganisationTrustees_OnFailingToUpdate_ReturnsBadRequestResponse()
{
var request = AutoFixture.Create<UpdateOrganisationTrusteesRequest>();
_mediator.Setup(x => x.Send(It.IsAny<UpdateOrganisationTrusteesRequest>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(false);
var result = await _controller.UpdateOrganisationTrustees(request);
result.Should().BeOfType<ActionResult<bool>>();
_mediator.Verify(x => x.Send(It.Is<UpdateOrganisationTrusteesRequest>(r => r.Trustees == request.Trustees && r.Ukprn == request.Ukprn && r.UpdatedBy == request.UpdatedBy), It.IsAny<CancellationToken>()), Times.Once);

result.Result.Should().BeOfType<BadRequestResult>();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,20 @@ public async Task<ActionResult<bool>> UpdateOrganisationDirectorsAndPscs([FromBo
return Ok(result);
}

[HttpPut("Trustees")]
[PerformValidation]
public async Task<ActionResult<bool>> UpdateOrganisationTrustees([FromBody] UpdateOrganisationTrusteesRequest request)
{
var result = await _mediator.Send(request);

if (result is false)
{
return BadRequest();
}

return Ok(result);
}

[HttpGet("name/{name}")]
public async Task<ActionResult<Organisation>> GetOrganisationByName(string name)
{
Expand Down Expand Up @@ -107,6 +121,19 @@ public async Task<ActionResult<Organisation>> GetOrganisationById(Guid organisat
return Ok(org);
}

[HttpGet("applicationId/{applicationId}")]
public async Task<ActionResult<Organisation>> GetOrganisationByApplicationId(Guid applicationId)
{
var org = await _mediator.Send(new GetOrganisationByApplicationIdRequest(applicationId));

if (org is null)
{
return NotFound();
}

return Ok(org);
}

[HttpGet("ukprn/{ukprn}")]
public async Task<ActionResult<Organisation>> GetOrganisationByUkprn(string ukprn)
{
Expand Down
Loading

0 comments on commit 4b0611f

Please sign in to comment.