diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Controllers/ApprenticeControllerTests/ApprenticeControllerTestBase.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Controllers/ApprenticeControllerTests/ApprenticeControllerTestBase.cs new file mode 100644 index 000000000..cddf97ae7 --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Controllers/ApprenticeControllerTests/ApprenticeControllerTestBase.cs @@ -0,0 +1,22 @@ +using Moq; +using SFA.DAS.CommitmentsV2.Api.Client; +using SFA.DAS.CommitmentsV2.Shared.Interfaces; +using SFA.DAS.EmployerCommitmentsV2.Web.Controllers; +using SFA.DAS.EmployerCommitmentsV2.Web.Models.Apprentice; +using SFA.DAS.EmployerUrlHelper; + +namespace SFA.DAS.EmployerCommitmentsV2.Web.UnitTests.Controllers.ApprenticeControllerTests +{ + public class ApprenticeControllerTestBase + { + protected const string _apprenticeshipDetailsUrl = "https://commitments.apprenticeships.gov.uk/accounts/apprentices/ABC123/details"; + protected const string _apprenticeshipStopUrl = "https://commitments.apprenticeships.gov.uk/accounts/apprentices/ABC123/stop/whentoapply"; + + protected Mock _mockModelMapper; + protected Mock> _mockCookieStorageService; + protected Mock _mockCommitmentsApiClient; + protected Mock _mockLinkGenerator; + + protected ApprenticeController _controller; + } +} diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Controllers/ApprenticeControllerTests/WhenPostingChangeStatus.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Controllers/ApprenticeControllerTests/WhenPostingChangeStatus.cs new file mode 100644 index 000000000..1e64942c2 --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Controllers/ApprenticeControllerTests/WhenPostingChangeStatus.cs @@ -0,0 +1,62 @@ +using Microsoft.AspNetCore.Mvc; +using Moq; +using NUnit.Framework; +using SFA.DAS.CommitmentsV2.Api.Client; +using SFA.DAS.CommitmentsV2.Shared.Interfaces; +using SFA.DAS.EmployerCommitmentsV2.Web.Controllers; +using SFA.DAS.EmployerCommitmentsV2.Web.Models.Apprentice; +using SFA.DAS.EmployerUrlHelper; +using SFA.DAS.Testing.AutoFixture; + +namespace SFA.DAS.EmployerCommitmentsV2.Web.UnitTests.Controllers.ApprenticeControllerTests +{ + public class WhenPostingChangeStatus : ApprenticeControllerTestBase + { + [SetUp] + public void Arrange() + { + _mockModelMapper = new Mock(); + _mockCookieStorageService = new Mock>(); + _mockCommitmentsApiClient = new Mock(); + _mockLinkGenerator = new Mock(); + + _controller = new ApprenticeController(_mockModelMapper.Object, _mockCookieStorageService.Object, _mockCommitmentsApiClient.Object, _mockLinkGenerator.Object); + } + + [Test, MoqAutoData] + public void AndPauseIsSelected_ThenRedirectToPauseApprenticeshipAction(ChangeStatusRequestViewModel viewModel) + { + viewModel.SelectedStatusChange = ChangeStatusType.Pause; + + var response = _controller.ChangeStatus(viewModel) as RedirectToActionResult; + + Assert.AreEqual("PauseApprenticeship", response.ActionName); + } + + [Test, MoqAutoData] + public void AndGoBackIsSelected_ThenRedirectToPauseApprenticeshipAction(ChangeStatusRequestViewModel viewModel) + { + viewModel.SelectedStatusChange = ChangeStatusType.GoBack; + + _mockLinkGenerator.Setup(p => p.CommitmentsLink($"accounts/{viewModel.AccountHashedId}/apprentices/manage/{viewModel.ApprenticeshipHashedId}/details")) + .Returns(_apprenticeshipDetailsUrl); + + var response = _controller.ChangeStatus(viewModel) as RedirectResult; + + Assert.AreEqual(_apprenticeshipDetailsUrl, response.Url); + } + + [Test, MoqAutoData] + public void AndStopIsSelected_ThenRedirectToV1WhenToApplyStopAction(ChangeStatusRequestViewModel viewModel) + { + viewModel.SelectedStatusChange = ChangeStatusType.Stop; + + _mockLinkGenerator.Setup(p => p.CommitmentsLink($"accounts/{viewModel.AccountHashedId}/apprentices/manage/{viewModel.ApprenticeshipHashedId}/details/statuschange/stop/whentoapply")) + .Returns(_apprenticeshipStopUrl); + + var response = _controller.ChangeStatus(viewModel) as RedirectResult; + + Assert.AreEqual(_apprenticeshipStopUrl, response.Url); + } + } +} diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Controllers/ApprenticeControllerTests/WhenPostingPauseRequestConfirmation.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Controllers/ApprenticeControllerTests/WhenPostingPauseRequestConfirmation.cs new file mode 100644 index 000000000..bbf677f74 --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Controllers/ApprenticeControllerTests/WhenPostingPauseRequestConfirmation.cs @@ -0,0 +1,80 @@ +using Microsoft.AspNetCore.Mvc; +using Moq; +using NUnit.Framework; +using SFA.DAS.CommitmentsV2.Api.Client; +using SFA.DAS.CommitmentsV2.Api.Types.Requests; +using SFA.DAS.CommitmentsV2.Shared.Interfaces; +using SFA.DAS.EmployerCommitmentsV2.Web.Controllers; +using SFA.DAS.EmployerCommitmentsV2.Web.Models.Apprentice; +using SFA.DAS.EmployerUrlHelper; +using SFA.DAS.Testing.AutoFixture; +using System.Threading; +using System.Threading.Tasks; + +namespace SFA.DAS.EmployerCommitmentsV2.Web.UnitTests.Controllers.ApprenticeControllerTests +{ + [TestFixture] + public class WhenPostingPauseRequestConfirmation : ApprenticeControllerTestBase + { + [SetUp] + public void Arrange() + { + _mockModelMapper = new Mock(); + _mockCookieStorageService = new Mock>(); + _mockCommitmentsApiClient = new Mock(); + _mockLinkGenerator = new Mock(); + + _controller = new ApprenticeController(_mockModelMapper.Object, _mockCookieStorageService.Object, _mockCommitmentsApiClient.Object, _mockLinkGenerator.Object); + } + + [Test, MoqAutoData] + public async Task AndConfirmPauseIsSelected_ThenCommitmentsApiPauseApprenticeshipIsCalled(PauseRequestViewModel request) + { + _mockLinkGenerator.Setup(p => p.CommitmentsLink($"accounts/{request.AccountHashedId}/apprentices/manage/{request.ApprenticeshipHashedId}/details")) + .Returns(_apprenticeshipDetailsUrl); + + var result = await _controller.PauseApprenticeship(request); + + _mockCommitmentsApiClient.Verify(p => p.PauseApprenticeship(It.IsAny(), It.IsAny()), Times.Once); + } + + [Test, MoqAutoData] + public async Task AndConfirmPauseIsSelected_ThenRedirectToApprenticeDetailsPage(PauseRequestViewModel request) + { + request.PauseConfirmed = true; + + _mockLinkGenerator.Setup(p => p.CommitmentsLink($"accounts/{request.AccountHashedId}/apprentices/manage/{request.ApprenticeshipHashedId}/details")) + .Returns(_apprenticeshipDetailsUrl); + + var result = await _controller.PauseApprenticeship(request) as RedirectResult; + + Assert.AreEqual(_apprenticeshipDetailsUrl, result.Url); + } + + [Test, MoqAutoData] + public async Task AndGoBackIsSelected_ThenCommitmentsApiPauseApprenticeshipIsNotCalled(PauseRequestViewModel request) + { + request.PauseConfirmed = false; + + _mockLinkGenerator.Setup(p => p.CommitmentsLink($"accounts/{request.AccountHashedId}/apprentices/manage/{request.ApprenticeshipHashedId}/details")) + .Returns(_apprenticeshipDetailsUrl); + + var result = await _controller.PauseApprenticeship(request); + + _mockCommitmentsApiClient.Verify(p => p.PauseApprenticeship(It.IsAny(), It.IsAny()), Times.Never); + } + + [Test, MoqAutoData] + public async Task AndGoBackIsSelected_ThenRedirectToApprenticeDetailsPage(PauseRequestViewModel request) + { + request.PauseConfirmed = false; + + _mockLinkGenerator.Setup(p => p.CommitmentsLink($"accounts/{request.AccountHashedId}/apprentices/manage/{request.ApprenticeshipHashedId}/details")) + .Returns(_apprenticeshipDetailsUrl); + + var result = await _controller.PauseApprenticeship(request) as RedirectResult; + + Assert.AreEqual(_apprenticeshipDetailsUrl, result.Url); + } + } +} diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Controllers/ApprenticeControllerTests/WhenPostingResumeRequestConfirmation.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Controllers/ApprenticeControllerTests/WhenPostingResumeRequestConfirmation.cs new file mode 100644 index 000000000..c693f0fb5 --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Controllers/ApprenticeControllerTests/WhenPostingResumeRequestConfirmation.cs @@ -0,0 +1,81 @@ +using Microsoft.AspNetCore.Mvc; +using Moq; +using NUnit.Framework; +using SFA.DAS.CommitmentsV2.Api.Client; +using SFA.DAS.CommitmentsV2.Api.Types.Requests; +using SFA.DAS.CommitmentsV2.Shared.Interfaces; +using SFA.DAS.EmployerCommitmentsV2.Web.Controllers; +using SFA.DAS.EmployerCommitmentsV2.Web.Models.Apprentice; +using SFA.DAS.EmployerUrlHelper; +using SFA.DAS.Testing.AutoFixture; +using System.Threading; +using System.Threading.Tasks; + +namespace SFA.DAS.EmployerCommitmentsV2.Web.UnitTests.Controllers.ApprenticeControllerTests +{ + [TestFixture] + public class WhenPostingResumeRequestConfirmation : ApprenticeControllerTestBase + { + [SetUp] + public void Arrange() + { + _mockModelMapper = new Mock(); + _mockCookieStorageService = new Mock>(); + _mockCommitmentsApiClient = new Mock(); + _mockLinkGenerator = new Mock(); + + _controller = new ApprenticeController(_mockModelMapper.Object, _mockCookieStorageService.Object, _mockCommitmentsApiClient.Object, _mockLinkGenerator.Object); + } + + [Test, MoqAutoData] + public async Task AndConfirmResumeIsSelected_ThenCommitmentsApiResumeApprenticeshipIsCalled(ResumeRequestViewModel request) + { + _mockLinkGenerator.Setup(p => p.CommitmentsLink($"accounts/{request.AccountHashedId}/apprentices/manage/{request.ApprenticeshipHashedId}/details")) + .Returns(_apprenticeshipDetailsUrl); + + await _controller.ResumeApprenticeship(request); + + _mockCommitmentsApiClient.Verify(p => + p.ResumeApprenticeship(It.IsAny(), It.IsAny()), Times.Once); + } + + [Test, MoqAutoData] + public async Task AndConfirmResumeIsSelected_ThenRedirectToApprenticeDetailsPage(ResumeRequestViewModel request) + { + request.ResumeConfirmed = true; + + _mockLinkGenerator.Setup(p => p.CommitmentsLink($"accounts/{request.AccountHashedId}/apprentices/manage/{request.ApprenticeshipHashedId}/details")) + .Returns(_apprenticeshipDetailsUrl); + + var result = await _controller.ResumeApprenticeship(request) as RedirectResult; + + Assert.AreEqual(_apprenticeshipDetailsUrl, result.Url); + } + + [Test, MoqAutoData] + public async Task AndGoBackIsSelected_ThenCommitmentsApiResumeApprenticeshipIsNotCalled(ResumeRequestViewModel request) + { + request.ResumeConfirmed = false; + + _mockLinkGenerator.Setup(p => p.CommitmentsLink($"accounts/{request.AccountHashedId}/apprentices/manage/{request.ApprenticeshipHashedId}/details")) + .Returns(_apprenticeshipDetailsUrl); + + await _controller.ResumeApprenticeship(request); + + _mockCommitmentsApiClient.Verify(p => p.ResumeApprenticeship(It.IsAny(), It.IsAny()), Times.Never); + } + + [Test, MoqAutoData] + public async Task AndGoBackIsSelected_ThenRedirectToApprenticeDetailsPage(ResumeRequestViewModel request) + { + request.ResumeConfirmed = false; + + _mockLinkGenerator.Setup(p => p.CommitmentsLink($"accounts/{request.AccountHashedId}/apprentices/manage/{request.ApprenticeshipHashedId}/details")) + .Returns(_apprenticeshipDetailsUrl); + + var result = await _controller.ResumeApprenticeship(request) as RedirectResult; + + Assert.AreEqual(_apprenticeshipDetailsUrl, result.Url); + } + } +} diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Controllers/ApprenticeControllerTests/WhenRequestingChangeStatusPage.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Controllers/ApprenticeControllerTests/WhenRequestingChangeStatusPage.cs new file mode 100644 index 000000000..a2081b9ee --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Controllers/ApprenticeControllerTests/WhenRequestingChangeStatusPage.cs @@ -0,0 +1,38 @@ +using Microsoft.AspNetCore.Mvc; +using Moq; +using NUnit.Framework; +using SFA.DAS.CommitmentsV2.Api.Client; +using SFA.DAS.CommitmentsV2.Shared.Interfaces; +using SFA.DAS.CommitmentsV2.Types; +using SFA.DAS.EmployerCommitmentsV2.Web.Controllers; +using SFA.DAS.EmployerCommitmentsV2.Web.Models.Apprentice; +using SFA.DAS.EmployerUrlHelper; +using System.Threading.Tasks; + +namespace SFA.DAS.EmployerCommitmentsV2.Web.UnitTests.Controllers.ApprenticeControllerTests +{ + public class WhenRequestingChangeStatusPage : ApprenticeControllerTestBase + { + [SetUp] + public void Arrange() + { + _mockModelMapper = new Mock(); + _mockCookieStorageService = new Mock>(); + _mockCommitmentsApiClient = new Mock(); + _mockLinkGenerator = new Mock(); + + _controller = new ApprenticeController(_mockModelMapper.Object, _mockCookieStorageService.Object, _mockCommitmentsApiClient.Object, _mockLinkGenerator.Object); + } + + [Test] + public async Task AndCurrentStatusIsLive_ThenViewIsReturned() + { + _mockModelMapper.Setup(m => m.Map(It.IsAny())) + .ReturnsAsync(new ChangeStatusRequestViewModel { CurrentStatus = ApprenticeshipStatus.Live }); + + var result = await _controller.ChangeStatus(new ChangeStatusRequest()); + + Assert.IsInstanceOf(result); + } + } +} diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Controllers/ApprenticeControllerTests/WhenRequestingPauseApprenticeshipConfirmationPage.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Controllers/ApprenticeControllerTests/WhenRequestingPauseApprenticeshipConfirmationPage.cs new file mode 100644 index 000000000..6d3cd8986 --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Controllers/ApprenticeControllerTests/WhenRequestingPauseApprenticeshipConfirmationPage.cs @@ -0,0 +1,53 @@ +using Microsoft.AspNetCore.Mvc; +using Moq; +using NUnit.Framework; +using SFA.DAS.CommitmentsV2.Api.Client; +using SFA.DAS.CommitmentsV2.Shared.Interfaces; +using SFA.DAS.EmployerCommitmentsV2.Web.Controllers; +using SFA.DAS.EmployerCommitmentsV2.Web.Models.Apprentice; +using SFA.DAS.EmployerUrlHelper; +using SFA.DAS.Testing.AutoFixture; +using System.Threading.Tasks; + +namespace SFA.DAS.EmployerCommitmentsV2.Web.UnitTests.Controllers.ApprenticeControllerTests +{ + public class WhenRequestingPauseApprenticeshipConfirmationPage : ApprenticeControllerTestBase + { + [SetUp] + public void Arrange() + { + _mockModelMapper = new Mock(); + _mockCookieStorageService = new Mock>(); + _mockCommitmentsApiClient = new Mock(); + _mockLinkGenerator = new Mock(); + + _controller = new ApprenticeController(_mockModelMapper.Object, _mockCookieStorageService.Object, _mockCommitmentsApiClient.Object, _mockLinkGenerator.Object); + } + + [Test] + public async Task AndCurrentStatusIsLive_ThenViewIsReturned() + { + _mockModelMapper.Setup(m => m.Map(It.IsAny())) + .ReturnsAsync(new PauseRequestViewModel()); + + var result = await _controller.PauseApprenticeship(new PauseRequest()); + + Assert.IsInstanceOf(result); + } + + [Test, MoqAutoData] + public async Task AndCurrentStatusIsLive_ThenPauseRequestViewModelIsPassedToTheView(PauseRequestViewModel _viewModel) + { + _mockModelMapper.Setup(m => m.Map(It.IsAny())) + .ReturnsAsync(_viewModel); + + var viewResult = await _controller.PauseApprenticeship(new PauseRequest()) as ViewResult; + var viewModel = viewResult.Model; + + var pauseRequestViewModel = (PauseRequestViewModel)viewModel; + + Assert.IsInstanceOf(viewModel); + Assert.AreEqual(_viewModel, pauseRequestViewModel); + } + } +} diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Controllers/ApprenticeControllerTests/WhenRequestingResumeApprenticeshipConfirmationPage.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Controllers/ApprenticeControllerTests/WhenRequestingResumeApprenticeshipConfirmationPage.cs new file mode 100644 index 000000000..abcb07602 --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Controllers/ApprenticeControllerTests/WhenRequestingResumeApprenticeshipConfirmationPage.cs @@ -0,0 +1,45 @@ +using System; +using Microsoft.AspNetCore.Mvc; +using Moq; +using NUnit.Framework; +using SFA.DAS.CommitmentsV2.Api.Client; +using SFA.DAS.CommitmentsV2.Shared.Interfaces; +using SFA.DAS.EmployerCommitmentsV2.Web.Controllers; +using SFA.DAS.EmployerCommitmentsV2.Web.Models.Apprentice; +using SFA.DAS.EmployerUrlHelper; +using System.Threading.Tasks; + +namespace SFA.DAS.EmployerCommitmentsV2.Web.UnitTests.Controllers.ApprenticeControllerTests +{ + public class WhenRequestingResumeApprenticeshipConfirmationPage : ApprenticeControllerTestBase + { + [SetUp] + public void Arrange() + { + _mockModelMapper = new Mock(); + _mockCookieStorageService = new Mock>(); + _mockCommitmentsApiClient = new Mock(); + _mockLinkGenerator = new Mock(); + + _controller = new ApprenticeController(_mockModelMapper.Object, _mockCookieStorageService.Object, _mockCommitmentsApiClient.Object, _mockLinkGenerator.Object); + } + + [Test] + public async Task AndCurrentStatusIsPaused_ThenViewIsReturned() + { + DateTime resumedDate = DateTime.Now; + _mockModelMapper.Setup(m => m.Map(It.IsAny())) + .ReturnsAsync(new ResumeRequestViewModel() + { + ResumeDate = resumedDate + }); + + var result = await _controller.ResumeApprenticeship(new ResumeRequest()); + + var viewResult = (ViewResult)result; + var viewModel = viewResult.Model; + Assert.That(viewModel, Is.TypeOf()); + Assert.IsInstanceOf(result); + } + } +} diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Mappers/Apprentice/ChangeSatusRequestToViewModelMapperTests.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Mappers/Apprentice/ChangeSatusRequestToViewModelMapperTests.cs new file mode 100644 index 000000000..e84f34e5e --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Mappers/Apprentice/ChangeSatusRequestToViewModelMapperTests.cs @@ -0,0 +1,64 @@ +using AutoFixture; +using Moq; +using NUnit.Framework; +using SFA.DAS.CommitmentsV2.Api.Client; +using SFA.DAS.CommitmentsV2.Api.Types.Responses; +using SFA.DAS.CommitmentsV2.Types; +using SFA.DAS.EmployerCommitmentsV2.Web.Mappers.Apprentice; +using SFA.DAS.EmployerCommitmentsV2.Web.Models.Apprentice; +using SFA.DAS.Testing.AutoFixture; +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace SFA.DAS.EmployerCommitmentsV2.Web.UnitTests.Mappers.Apprentice +{ + [TestFixture] + public class WhenMapping_ChangeSatusRequestToViewModelMapperTests + { + private ChangeStatusRequestToViewModelMapper _mapper; + private Mock _mockCommitmentsApiClient; + + [SetUp] + public void Arrange() + { + + + _mockCommitmentsApiClient = new Mock(); + + _mapper = new ChangeStatusRequestToViewModelMapper(_mockCommitmentsApiClient.Object); + + _mockCommitmentsApiClient.Setup(a => a.GetApprenticeship(It.IsAny(), It.IsAny())) + .ReturnsAsync(new GetApprenticeshipResponse + { + Status = ApprenticeshipStatus.Completed + }); + } + + [Test, MoqAutoData] + public async Task ThenApprenticeshipHashedIdIsMappedCorrectly(ChangeStatusRequest request) + { + var result = await _mapper.Map(request); + + Assert.AreEqual(request.ApprenticeshipHashedId, result.ApprenticeshipHashedId); + } + + [Test, MoqAutoData] + public async Task ThenAccountHashedIdIsMappedCorrectly(ChangeStatusRequest request) + { + var result = await _mapper.Map(request); + + Assert.AreEqual(request.AccountHashedId, result.AccountHashedId); + } + + [Test, MoqAutoData] + public async Task ThenCurrentStatusIsMapped(ChangeStatusRequest request) + { + var result = await _mapper.Map(request); + + Assert.AreEqual(ApprenticeshipStatus.Completed, result.CurrentStatus); + } + } +} diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Mappers/Apprentice/PauseRequestToViewModelMapperTests.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Mappers/Apprentice/PauseRequestToViewModelMapperTests.cs new file mode 100644 index 000000000..7197da436 --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Mappers/Apprentice/PauseRequestToViewModelMapperTests.cs @@ -0,0 +1,86 @@ +using Moq; +using NUnit.Framework; +using SFA.DAS.CommitmentsV2.Api.Client; +using SFA.DAS.CommitmentsV2.Api.Types.Responses; +using SFA.DAS.EmployerCommitmentsV2.Web.Mappers.Apprentice; +using SFA.DAS.EmployerCommitmentsV2.Web.Models.Apprentice; +using SFA.DAS.Testing.AutoFixture; +using System.Threading; +using System.Threading.Tasks; + +namespace SFA.DAS.EmployerCommitmentsV2.Web.UnitTests.Mappers.Apprentice +{ + public class PauseRequestToViewModelMapperTests + { + private const string ExpectedFullName = "FirstName LastName"; + private const string ExpectedCourseName = "Test Apprenticeship"; + private const string ExpectedUln = "1234567890"; + + private Mock mockCommitmentsApiClient; + + [SetUp] + public void SetUp() + { + mockCommitmentsApiClient = new Mock(); + + mockCommitmentsApiClient + .Setup(r => r.GetApprenticeship(It.IsAny(), CancellationToken.None)) + .ReturnsAsync(GetApprenticeshipResponse()); + } + [Test, MoqAutoData] + public async Task ApprenticeshipHashedId_IsMapped(PauseRequest request) + { + var mapper = new PauseRequestToViewModelMapper(mockCommitmentsApiClient.Object); + var result = await mapper.Map(request); + + Assert.AreEqual(request.ApprenticeshipHashedId, result.ApprenticeshipHashedId); + } + + [Test, MoqAutoData] + public async Task AccountHashedId_IsMapped(PauseRequest request) + { + var mapper = new PauseRequestToViewModelMapper(mockCommitmentsApiClient.Object); + var result = await mapper.Map(request); + + Assert.AreEqual(request.AccountHashedId, result.AccountHashedId); + } + + [Test, MoqAutoData] + public async Task ApprenticeName_IsMapped(PauseRequest request) + { + var mapper = new PauseRequestToViewModelMapper(mockCommitmentsApiClient.Object); + var result = await mapper.Map(request); + + Assert.AreEqual(ExpectedFullName, result.ApprenticeName); + } + + [Test, MoqAutoData] + public async Task CourseName_IsMapped(PauseRequest request) + { + var mapper = new PauseRequestToViewModelMapper(mockCommitmentsApiClient.Object); + var result = await mapper.Map(request); + + Assert.AreEqual(ExpectedCourseName, result.Course); + } + + [Test, MoqAutoData] + public async Task ULN_IsMapped(PauseRequest request) + { + var mapper = new PauseRequestToViewModelMapper(mockCommitmentsApiClient.Object); + var result = await mapper.Map(request); + + Assert.AreEqual(ExpectedUln, result.ULN); + } + + private GetApprenticeshipResponse GetApprenticeshipResponse() + { + return new GetApprenticeshipResponse + { + FirstName = "FirstName", + LastName = "LastName", + Uln = "1234567890", + CourseName = "Test Apprenticeship" + }; + } + } +} diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Mappers/Apprentice/ResumeRequestToViewModelMapperTests.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Mappers/Apprentice/ResumeRequestToViewModelMapperTests.cs new file mode 100644 index 000000000..93d99ead4 --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Mappers/Apprentice/ResumeRequestToViewModelMapperTests.cs @@ -0,0 +1,86 @@ +using Moq; +using NUnit.Framework; +using SFA.DAS.CommitmentsV2.Api.Client; +using SFA.DAS.CommitmentsV2.Api.Types.Responses; +using SFA.DAS.EmployerCommitmentsV2.Web.Mappers.Apprentice; +using SFA.DAS.EmployerCommitmentsV2.Web.Models.Apprentice; +using SFA.DAS.Testing.AutoFixture; +using System.Threading; +using System.Threading.Tasks; + +namespace SFA.DAS.EmployerCommitmentsV2.Web.UnitTests.Mappers.Apprentice +{ + public class ResumeRequestToViewModelMapperTests + { + private const string ExpectedFullName = "FirstName LastName"; + private const string ExpectedCourseName = "Test Apprenticeship"; + private const string ExpectedUln = "1234567890"; + + private Mock mockCommitmentsApiClient; + + [SetUp] + public void SetUp() + { + mockCommitmentsApiClient = new Mock(); + + mockCommitmentsApiClient + .Setup(r => r.GetApprenticeship(It.IsAny(), CancellationToken.None)) + .ReturnsAsync(GetApprenticeshipResponse()); + } + [Test, MoqAutoData] + public async Task ApprenticeshipHashedId_IsMapped(ResumeRequest request) + { + var mapper = new ResumeRequestToViewModelMapper(mockCommitmentsApiClient.Object); + var result = await mapper.Map(request); + + Assert.AreEqual(request.ApprenticeshipHashedId, result.ApprenticeshipHashedId); + } + + [Test, MoqAutoData] + public async Task AccountHashedId_IsMapped(ResumeRequest request) + { + var mapper = new ResumeRequestToViewModelMapper(mockCommitmentsApiClient.Object); + var result = await mapper.Map(request); + + Assert.AreEqual(request.AccountHashedId, result.AccountHashedId); + } + + [Test, MoqAutoData] + public async Task ApprenticeName_IsMapped(ResumeRequest request) + { + var mapper = new ResumeRequestToViewModelMapper(mockCommitmentsApiClient.Object); + var result = await mapper.Map(request); + + Assert.AreEqual(ExpectedFullName, result.ApprenticeName); + } + + [Test, MoqAutoData] + public async Task CourseName_IsMapped(ResumeRequest request) + { + var mapper = new ResumeRequestToViewModelMapper(mockCommitmentsApiClient.Object); + var result = await mapper.Map(request); + + Assert.AreEqual(ExpectedCourseName, result.Course); + } + + [Test, MoqAutoData] + public async Task ULN_IsMapped(ResumeRequest request) + { + var mapper = new ResumeRequestToViewModelMapper(mockCommitmentsApiClient.Object); + var result = await mapper.Map(request); + + Assert.AreEqual(ExpectedUln, result.ULN); + } + + private GetApprenticeshipResponse GetApprenticeshipResponse() + { + return new GetApprenticeshipResponse + { + FirstName = "FirstName", + LastName = "LastName", + Uln = "1234567890", + CourseName = "Test Apprenticeship" + }; + } + } +} diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Mappers/Cohort/EditDraftApprenticeshipDetailsToViewModelMapperTests.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Mappers/Cohort/EditDraftApprenticeshipDetailsToViewModelMapperTests.cs index 0ede5ee39..46db18a12 100644 --- a/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Mappers/Cohort/EditDraftApprenticeshipDetailsToViewModelMapperTests.cs +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Mappers/Cohort/EditDraftApprenticeshipDetailsToViewModelMapperTests.cs @@ -37,7 +37,7 @@ public async Task ThenDraftApprenticeshipIdIsMappedCorrectly() public async Task ThenDraftApprenticeshipHashedIdIsMappedCorrectly() { var result = await _act(); - Assert.AreEqual(_source.DraftApprenticeshipId, result.DraftApprenticeshipId); + Assert.AreEqual(_source.DraftApprenticeshipHashedId, result.DraftApprenticeshipHashedId); } [Test] diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests.csproj b/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests.csproj index 9086eeb8d..4fd6fd479 100644 --- a/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests.csproj +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests.csproj @@ -17,8 +17,8 @@ - - + + diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Validators/ChangeStatusRequestViewModelValidatorTests.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Validators/ChangeStatusRequestViewModelValidatorTests.cs new file mode 100644 index 000000000..77bc60711 --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Validators/ChangeStatusRequestViewModelValidatorTests.cs @@ -0,0 +1,44 @@ +using NUnit.Framework; +using System; +using SFA.DAS.EmployerCommitmentsV2.Web.Models.Apprentice; +using SFA.DAS.EmployerCommitmentsV2.Web.Validators; +using System.Linq.Expressions; +using FluentValidation.TestHelper; + +namespace SFA.DAS.EmployerCommitmentsV2.Web.UnitTests.Validators +{ + [TestFixture()] + public class ChangeStatusRequestViewModelValidatorTests + { + [TestCase(ChangeStatusType.Stop)] + [TestCase(ChangeStatusType.Pause)] + [TestCase(ChangeStatusType.GoBack)] + public void Validate_ChangeStatusType_ShouldBeValidated(ChangeStatusType status) + { + var model = new ChangeStatusRequestViewModel { SelectedStatusChange = status }; + + AssertValidationResult(request => request.SelectedStatusChange, model, true); + } + + [Test] + public void Validate_ChangeStatusType_WhenNotSelected_ThenItShouldBeInvalid() + { + var model = new ChangeStatusRequestViewModel { SelectedStatusChange = null }; + + AssertValidationResult(request => request.SelectedStatusChange, model, false); + } + private void AssertValidationResult(Expression> property, ChangeStatusRequestViewModel instance, bool expectedValid) + { + var validator = new ChangeStatusRequestViewModelValidator(); + + if (expectedValid) + { + validator.ShouldNotHaveValidationErrorFor(property, instance); + } + else + { + validator.ShouldHaveValidationErrorFor(property, instance); + } + } + } +} diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Validators/EditDraftApprenticeshipViewModelValidatorTests.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Validators/EditDraftApprenticeshipViewModelValidatorTests.cs index c09c6c503..56b060fea 100644 --- a/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Validators/EditDraftApprenticeshipViewModelValidatorTests.cs +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Validators/EditDraftApprenticeshipViewModelValidatorTests.cs @@ -2,7 +2,6 @@ using System.Linq.Expressions; using FluentValidation.TestHelper; using NUnit.Framework; -using SFA.DAS.EmployerCommitmentsV2.Web.Models; using SFA.DAS.EmployerCommitmentsV2.Web.Models.DraftApprenticeship; using SFA.DAS.EmployerCommitmentsV2.Web.Validators; diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Validators/PauseRequestValidatorTests.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Validators/PauseRequestValidatorTests.cs new file mode 100644 index 000000000..a35f68827 --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Validators/PauseRequestValidatorTests.cs @@ -0,0 +1,52 @@ +using FluentValidation.TestHelper; +using NUnit.Framework; +using SFA.DAS.EmployerCommitmentsV2.Web.Models.Apprentice; +using SFA.DAS.EmployerCommitmentsV2.Web.Validators; +using System; +using System.Collections.Generic; +using System.Linq.Expressions; +using System.Text; + +namespace SFA.DAS.EmployerCommitmentsV2.Web.UnitTests.Validators +{ + [TestFixture] + public class PauseRequestValidatorTests + { + [TestCase("", false)] + [TestCase(" ", false)] + [TestCase("testString", true)] + [TestCase(null, false)] + public void ThenValidatesAccountHashedId(string accountHashedId, bool expectedValid) + { + var request = new PauseRequest { AccountHashedId = accountHashedId }; + + AssertValidationResult(x => x.AccountHashedId, request, expectedValid); + } + + [TestCase("", false)] + [TestCase(" ", false)] + [TestCase("testString", true)] + [TestCase(null, false)] + public void ThenValidatesApprenticeshipHashedId(string apprenticeshipHashedId, bool expectedValid) + { + var request = new PauseRequest { ApprenticeshipHashedId = apprenticeshipHashedId }; + + AssertValidationResult(x => x.ApprenticeshipHashedId, request, expectedValid); + } + + + private void AssertValidationResult(Expression> property, PauseRequest instance, bool expectedValid) + { + var validator = new PauseRequestValidator(); + + if (expectedValid) + { + validator.ShouldNotHaveValidationErrorFor(property, instance); + } + else + { + validator.ShouldHaveValidationErrorFor(property, instance); + } + } + } +} diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Validators/PauseRequestViewModelValidatorTests.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Validators/PauseRequestViewModelValidatorTests.cs new file mode 100644 index 000000000..5d9c5b7a7 --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Validators/PauseRequestViewModelValidatorTests.cs @@ -0,0 +1,49 @@ +using NUnit.Framework; +using SFA.DAS.EmployerCommitmentsV2.Web.Models.Apprentice; +using SFA.DAS.EmployerCommitmentsV2.Web.Validators; +using SFA.DAS.Testing.AutoFixture; + +namespace SFA.DAS.EmployerCommitmentsV2.Web.UnitTests.Validators +{ + [TestFixture] + public class PauseRequestViewModelValidatorTests + { + private PauseRequestViewModelValidator _validator; + + [SetUp] + public void Arrange() + { + _validator = new PauseRequestViewModelValidator(); + } + + [Test, MoqAutoData] + public void WhenPauseConfirmedIsNull_ThenValidatorReturnsInvalid(PauseRequestViewModel viewModel) + { + viewModel.PauseConfirmed = null; + + var result = _validator.Validate(viewModel); + + Assert.False(result.IsValid); + } + + [Test, MoqAutoData] + public void WhenPauseConfirmedIsFalse_ThenValidatorReturnsValid(PauseRequestViewModel viewModel) + { + viewModel.PauseConfirmed = false; + + var result = _validator.Validate(viewModel); + + Assert.True(result.IsValid); + } + + [Test, MoqAutoData] + public void WhenPauseConfirmedIsTrue_ThenValidatorReturnsValid(PauseRequestViewModel viewModel) + { + viewModel.PauseConfirmed = true; + + var result = _validator.Validate(viewModel); + + Assert.True(result.IsValid); + } + } +} diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Controllers/ApprenticeController.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web/Controllers/ApprenticeController.cs index 9e51475c2..c6db21843 100644 --- a/src/SFA.DAS.EmployerCommitmentsV2.Web/Controllers/ApprenticeController.cs +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Controllers/ApprenticeController.cs @@ -111,5 +111,81 @@ public IActionResult EnterNewTrainingProvider() { return View(); } + + [Route("{apprenticeshipHashedId}/details/changestatus")] + [DasAuthorize(EmployerFeature.ManageApprenticesV2)] + [HttpGet] + public async Task ChangeStatus(ChangeStatusRequest request) + { + var viewModel = await _modelMapper.Map(request); + + return View(viewModel); + } + + [Route("{apprenticeshipHashedId}/details/changestatus")] + [DasAuthorize(EmployerFeature.ManageApprenticesV2)] + [HttpPost] + public IActionResult ChangeStatus(ChangeStatusRequestViewModel viewModel) + { + switch (viewModel.SelectedStatusChange) + { + case ChangeStatusType.Pause: + return RedirectToAction(nameof(PauseApprenticeship), new { viewModel.AccountHashedId, viewModel.ApprenticeshipHashedId }); + case ChangeStatusType.Stop: + return Redirect(_linkGenerator.WhenToApplyStopApprentice(viewModel.AccountHashedId, viewModel.ApprenticeshipHashedId)); + case ChangeStatusType.Resume: + return RedirectToAction(nameof(ResumeApprenticeship), new { viewModel.AccountHashedId, viewModel.ApprenticeshipHashedId }); + default: + return Redirect(_linkGenerator.ApprenticeDetails(viewModel.AccountHashedId, viewModel.ApprenticeshipHashedId)); + } + } + + [Route("{apprenticeshipHashedId}/details/pause")] + [DasAuthorize(EmployerFeature.ManageApprenticesV2)] + [HttpGet] + public async Task PauseApprenticeship(PauseRequest request) + { + var viewModel = await _modelMapper.Map(request); + return View(viewModel); + } + + [Route("{apprenticeshipHashedId}/details/pause")] + [DasAuthorize(EmployerFeature.ManageApprenticesV2)] + [HttpPost] + public async Task PauseApprenticeship(PauseRequestViewModel viewModel) + { + if (viewModel.PauseConfirmed.HasValue && viewModel.PauseConfirmed.Value) + { + var pauseRequest = new PauseApprenticeshipRequest { ApprenticeshipId = viewModel.ApprenticeshipId }; + + await _commitmentsApiClient.PauseApprenticeship(pauseRequest, CancellationToken.None); + } + + return Redirect(_linkGenerator.ApprenticeDetails(viewModel.AccountHashedId, viewModel.ApprenticeshipHashedId)); + } + + [DasAuthorize(EmployerFeature.ManageApprenticesV2)] + [Route("{apprenticeshipHashedId}/details/resume")] + [HttpGet] + public async Task ResumeApprenticeship(ResumeRequest request) + { + var viewModel = await _modelMapper.Map(request); + return View(viewModel); + } + + [DasAuthorize(EmployerFeature.ManageApprenticesV2)] + [Route("{apprenticeshipHashedId}/details/resume")] + [HttpPost] + public async Task ResumeApprenticeship(ResumeRequestViewModel viewModel) + { + if (viewModel.ResumeConfirmed.HasValue && viewModel.ResumeConfirmed.Value) + { + var resumeRequest = new ResumeApprenticeshipRequest { ApprenticeshipId = viewModel.ApprenticeshipId }; + + await _commitmentsApiClient.ResumeApprenticeship(resumeRequest, CancellationToken.None); + } + + return Redirect(_linkGenerator.ApprenticeDetails(viewModel.AccountHashedId, viewModel.ApprenticeshipHashedId)); + } } } \ No newline at end of file diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Controllers/ErrorController.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web/Controllers/ErrorController.cs index 44f2b6ee4..f5b9b7009 100644 --- a/src/SFA.DAS.EmployerCommitmentsV2.Web/Controllers/ErrorController.cs +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Controllers/ErrorController.cs @@ -6,7 +6,9 @@ public class ErrorController : Controller { [Route("error")] public IActionResult Error(int? statusCode) - { + { + ViewBag.HideNav = true; + switch (statusCode) { case 400: diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Extensions/ILinkGeneratorExtensions.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web/Extensions/ILinkGeneratorExtensions.cs index 2c33022c4..f6a7a109b 100644 --- a/src/SFA.DAS.EmployerCommitmentsV2.Web/Extensions/ILinkGeneratorExtensions.cs +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Extensions/ILinkGeneratorExtensions.cs @@ -22,6 +22,14 @@ public static string ApprenticeDetails( return linkGenerator.CommitmentsLink($"accounts/{accountHashedId}/apprentices/manage/{hashedApprenticeshipId}/details"); } + public static string WhenToApplyStopApprentice( + this ILinkGenerator linkGenerator, + string accountHashedId, + string hashedApprenticeshipId) + { + return linkGenerator.CommitmentsLink($"accounts/{accountHashedId}/apprentices/manage/{hashedApprenticeshipId}/details/statuschange/stop/whentoapply"); + } + public static string ViewApprentice(this ILinkGenerator linkGenerator, string accountHashedId, string cohortReference, @@ -42,5 +50,10 @@ public static string EmployerHome(this ILinkGenerator linkGenerator, string acco { return linkGenerator.AccountsLink($"accounts/{accountHashedId}/teams"); } + + public static string EmployerAccountsHome(this ILinkGenerator linkGenerator) + { + return linkGenerator.AccountsLink(); + } } } \ No newline at end of file diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Mappers/Apprentice/ChangeStatusRequestToViewModelMapper.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web/Mappers/Apprentice/ChangeStatusRequestToViewModelMapper.cs new file mode 100644 index 000000000..d14678385 --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Mappers/Apprentice/ChangeStatusRequestToViewModelMapper.cs @@ -0,0 +1,32 @@ +using SFA.DAS.CommitmentsV2.Api.Client; +using SFA.DAS.CommitmentsV2.Shared.Interfaces; +using SFA.DAS.EmployerCommitmentsV2.Web.Models.Apprentice; +using System.Threading.Tasks; + +namespace SFA.DAS.EmployerCommitmentsV2.Web.Mappers.Apprentice +{ + public class ChangeStatusRequestToViewModelMapper : IMapper + { + private readonly ICommitmentsApiClient _commitmentsApiClient; + + public ChangeStatusRequestToViewModelMapper(ICommitmentsApiClient commitmentsApiClient) + { + _commitmentsApiClient = commitmentsApiClient; + } + + public async Task Map(ChangeStatusRequest source) + { + var apprenticeship = await _commitmentsApiClient.GetApprenticeship(source.ApprenticeshipId); + + var result = new ChangeStatusRequestViewModel + { + AccountHashedId = source.AccountHashedId, + ApprenticeshipHashedId = source.ApprenticeshipHashedId, + ApprenticeshipId = source.ApprenticeshipId, + CurrentStatus = apprenticeship.Status + }; + + return result; + } + } +} diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Mappers/Apprentice/PauseRequestToViewModelMapper.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web/Mappers/Apprentice/PauseRequestToViewModelMapper.cs new file mode 100644 index 000000000..3f4b9dd37 --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Mappers/Apprentice/PauseRequestToViewModelMapper.cs @@ -0,0 +1,32 @@ +using SFA.DAS.CommitmentsV2.Api.Client; +using SFA.DAS.CommitmentsV2.Shared.Interfaces; +using SFA.DAS.EmployerCommitmentsV2.Web.Models.Apprentice; +using System; +using System.Threading.Tasks; + +namespace SFA.DAS.EmployerCommitmentsV2.Web.Mappers.Apprentice +{ + public class PauseRequestToViewModelMapper : IMapper + { + private readonly ICommitmentsApiClient _client; + public PauseRequestToViewModelMapper(ICommitmentsApiClient client) + { + _client = client; + } + + public async Task Map(PauseRequest source) + { + var apprenticeship = await _client.GetApprenticeship(source.ApprenticeshipId); + + return new PauseRequestViewModel + { + AccountHashedId = source.AccountHashedId, + ApprenticeshipHashedId = source.ApprenticeshipHashedId, + ApprenticeName = $"{apprenticeship.FirstName} {apprenticeship.LastName}", + ULN = apprenticeship.Uln, + Course = apprenticeship.CourseName, + PauseDate = DateTime.UtcNow + }; + } + } +} diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Mappers/Apprentice/ResumeRequestToViewModelMapper.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web/Mappers/Apprentice/ResumeRequestToViewModelMapper.cs new file mode 100644 index 000000000..35ad2e870 --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Mappers/Apprentice/ResumeRequestToViewModelMapper.cs @@ -0,0 +1,33 @@ +using SFA.DAS.CommitmentsV2.Api.Client; +using SFA.DAS.CommitmentsV2.Shared.Interfaces; +using SFA.DAS.EmployerCommitmentsV2.Web.Models.Apprentice; +using System; +using System.Threading.Tasks; + +namespace SFA.DAS.EmployerCommitmentsV2.Web.Mappers.Apprentice +{ + public class ResumeRequestToViewModelMapper : IMapper + { + private readonly ICommitmentsApiClient _client; + public ResumeRequestToViewModelMapper(ICommitmentsApiClient client) + { + _client = client; + } + + public async Task Map(ResumeRequest source) + { + var apprenticeship = await _client.GetApprenticeship(source.ApprenticeshipId); + + return new ResumeRequestViewModel + { + AccountHashedId = source.AccountHashedId, + ApprenticeshipHashedId = source.ApprenticeshipHashedId, + ApprenticeName = $"{apprenticeship.FirstName} {apprenticeship.LastName}", + ULN = apprenticeship.Uln, + Course = apprenticeship.CourseName, + PauseDate = apprenticeship.PauseDate, + ResumeDate = DateTime.UtcNow + }; + } + } +} diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Models/Apprentice/ChangeStatusRequest.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web/Models/Apprentice/ChangeStatusRequest.cs new file mode 100644 index 000000000..57b36956f --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Models/Apprentice/ChangeStatusRequest.cs @@ -0,0 +1,16 @@ +using Microsoft.AspNetCore.Mvc; +using SFA.DAS.Authorization.ModelBinding; + +namespace SFA.DAS.EmployerCommitmentsV2.Web.Models.Apprentice +{ + public class ChangeStatusRequest : IAuthorizationContextModel + { + [FromRoute] + public string AccountHashedId { get; set; } + + [FromRoute] + public string ApprenticeshipHashedId { get; set; } + + public long ApprenticeshipId { get; set; } + } +} diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Models/Apprentice/ChangeStatusRequestViewModel.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web/Models/Apprentice/ChangeStatusRequestViewModel.cs new file mode 100644 index 000000000..2f266d493 --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Models/Apprentice/ChangeStatusRequestViewModel.cs @@ -0,0 +1,29 @@ +using SFA.DAS.Authorization.ModelBinding; +using SFA.DAS.CommitmentsV2.Types; + +namespace SFA.DAS.EmployerCommitmentsV2.Web.Models.Apprentice +{ + public class ChangeStatusRequestViewModel : IAuthorizationContextModel + { + public ChangeStatusRequestViewModel() + { + } + + public string AccountHashedId { get; set; } + + public string ApprenticeshipHashedId { get; set; } + + public long ApprenticeshipId { get; set; } + + public ChangeStatusType? SelectedStatusChange { get; set; } + public ApprenticeshipStatus CurrentStatus { get; set; } + } + + public enum ChangeStatusType + { + Stop, + Pause, + GoBack, + Resume + } +} diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Models/Apprentice/PauseRequest.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web/Models/Apprentice/PauseRequest.cs new file mode 100644 index 000000000..e2ef03adf --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Models/Apprentice/PauseRequest.cs @@ -0,0 +1,16 @@ +using Microsoft.AspNetCore.Mvc; +using SFA.DAS.Authorization.ModelBinding; + +namespace SFA.DAS.EmployerCommitmentsV2.Web.Models.Apprentice +{ + public class PauseRequest : IAuthorizationContextModel + { + [FromRoute] + public string AccountHashedId { get; set; } + + [FromRoute] + public string ApprenticeshipHashedId { get; set; } + + public long ApprenticeshipId { get; set; } + } +} diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Models/Apprentice/PauseRequestViewModel.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web/Models/Apprentice/PauseRequestViewModel.cs new file mode 100644 index 000000000..571f26967 --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Models/Apprentice/PauseRequestViewModel.cs @@ -0,0 +1,28 @@ +using SFA.DAS.Authorization.ModelBinding; +using System; + +namespace SFA.DAS.EmployerCommitmentsV2.Web.Models.Apprentice +{ + public class PauseRequestViewModel : IAuthorizationContextModel + { + public PauseRequestViewModel() + { + } + + public string AccountHashedId { get; set; } + + public string ApprenticeshipHashedId { get; set; } + + public long ApprenticeshipId { get; set; } + + public string ApprenticeName { get; set; } + + public string ULN { get; set; } + + public string Course { get; set; } + + public DateTime PauseDate { get; set; } + + public bool? PauseConfirmed { get; set; } + } +} diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Models/Apprentice/ResumeRequest.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web/Models/Apprentice/ResumeRequest.cs new file mode 100644 index 000000000..0e4e51c87 --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Models/Apprentice/ResumeRequest.cs @@ -0,0 +1,14 @@ +using Microsoft.AspNetCore.Mvc; +using SFA.DAS.Authorization.ModelBinding; + +namespace SFA.DAS.EmployerCommitmentsV2.Web.Models.Apprentice +{ + public class ResumeRequest : IAuthorizationContextModel + { + [FromRoute] + public string AccountHashedId { get; set; } + [FromRoute] + public string ApprenticeshipHashedId { get; set; } + public long ApprenticeshipId { get; set; } + } +} diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Models/Apprentice/ResumeRequestViewModel.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web/Models/Apprentice/ResumeRequestViewModel.cs new file mode 100644 index 000000000..f1b5d794e --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Models/Apprentice/ResumeRequestViewModel.cs @@ -0,0 +1,29 @@ +using SFA.DAS.Authorization.ModelBinding; +using System; + +namespace SFA.DAS.EmployerCommitmentsV2.Web.Models.Apprentice +{ + public class ResumeRequestViewModel : IAuthorizationContextModel + { + public ResumeRequestViewModel() + { + } + + public string AccountHashedId { get; set; } + + public string ApprenticeshipHashedId { get; set; } + + public long ApprenticeshipId { get; set; } + + public string ApprenticeName { get; set; } + + public string ULN { get; set; } + + public string Course { get; set; } + + public DateTime? PauseDate { get; set; } + + public DateTime ResumeDate { get; set; } + public bool? ResumeConfirmed { get; set; } + } +} diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/SFA.DAS.EmployerCommitmentsV2.Web.csproj b/src/SFA.DAS.EmployerCommitmentsV2.Web/SFA.DAS.EmployerCommitmentsV2.Web.csproj index 32cb4dca2..141785860 100644 --- a/src/SFA.DAS.EmployerCommitmentsV2.Web/SFA.DAS.EmployerCommitmentsV2.Web.csproj +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/SFA.DAS.EmployerCommitmentsV2.Web.csproj @@ -25,8 +25,8 @@ - - + + diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Validators/ChangeStatusRequestValidator.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web/Validators/ChangeStatusRequestValidator.cs new file mode 100644 index 000000000..3f69689dd --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Validators/ChangeStatusRequestValidator.cs @@ -0,0 +1,14 @@ +using FluentValidation; +using SFA.DAS.EmployerCommitmentsV2.Web.Models.Apprentice; + +namespace SFA.DAS.EmployerCommitmentsV2.Web.Validators +{ + public class ChangeStatusRequestValidator : AbstractValidator + { + public ChangeStatusRequestValidator() + { + RuleFor(x => x.AccountHashedId).NotEmpty(); + RuleFor(x => x.ApprenticeshipHashedId).NotEmpty(); + } + } +} diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Validators/ChangeStatusRequestViewModelValidator.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web/Validators/ChangeStatusRequestViewModelValidator.cs new file mode 100644 index 000000000..041c6894e --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Validators/ChangeStatusRequestViewModelValidator.cs @@ -0,0 +1,15 @@ +using FluentValidation; +using SFA.DAS.EmployerCommitmentsV2.Web.Models.Apprentice; + +namespace SFA.DAS.EmployerCommitmentsV2.Web.Validators +{ + public class ChangeStatusRequestViewModelValidator : AbstractValidator + { + public ChangeStatusRequestViewModelValidator() + { + RuleFor(r => r.AccountHashedId).NotEmpty(); + RuleFor(r => r.ApprenticeshipHashedId).NotEmpty(); + RuleFor(r => r.SelectedStatusChange).NotNull().WithMessage("Select whether to change this apprenticeship status or not"); + } + } +} diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Validators/PauseRequestValidator.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web/Validators/PauseRequestValidator.cs new file mode 100644 index 000000000..e5124a896 --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Validators/PauseRequestValidator.cs @@ -0,0 +1,14 @@ +using FluentValidation; +using SFA.DAS.EmployerCommitmentsV2.Web.Models.Apprentice; + +namespace SFA.DAS.EmployerCommitmentsV2.Web.Validators +{ + public class PauseRequestValidator : AbstractValidator + { + public PauseRequestValidator() + { + RuleFor(x => x.AccountHashedId).NotEmpty(); + RuleFor(x => x.ApprenticeshipHashedId).NotEmpty(); + } + } +} diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Validators/PauseRequestViewModelValidator.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web/Validators/PauseRequestViewModelValidator.cs new file mode 100644 index 000000000..c83b1c3a9 --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Validators/PauseRequestViewModelValidator.cs @@ -0,0 +1,13 @@ +using FluentValidation; +using SFA.DAS.EmployerCommitmentsV2.Web.Models.Apprentice; + +namespace SFA.DAS.EmployerCommitmentsV2.Web.Validators +{ + public class PauseRequestViewModelValidator : AbstractValidator + { + public PauseRequestViewModelValidator() + { + RuleFor(r => r.PauseConfirmed).NotNull().WithMessage("Select whether to pause this apprenticeship or not"); + } + } +} diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Validators/ResumeRequestViewModelValidator.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web/Validators/ResumeRequestViewModelValidator.cs new file mode 100644 index 000000000..5799fb0ba --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Validators/ResumeRequestViewModelValidator.cs @@ -0,0 +1,14 @@ +using FluentValidation; +using SFA.DAS.EmployerCommitmentsV2.Web.Models.Apprentice; + +namespace SFA.DAS.EmployerCommitmentsV2.Web.Validators +{ + public class ResumeRequestViewModelValidator : AbstractValidator + { + public ResumeRequestViewModelValidator() + { + RuleFor(r => r.ResumeConfirmed).NotNull() + .WithMessage("Select whether to resume this apprenticeship or not"); + } + } +} diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Views/Apprentice/ChangeStatus.cshtml b/src/SFA.DAS.EmployerCommitmentsV2.Web/Views/Apprentice/ChangeStatus.cshtml new file mode 100644 index 000000000..9de12662c --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Views/Apprentice/ChangeStatus.cshtml @@ -0,0 +1,93 @@ +@inject ILinkGenerator LinkGenerator +@using SFA.DAS.CommitmentsV2.Shared.Extensions +@using SFA.DAS.CommitmentsV2.Types +@using SFA.DAS.EmployerCommitmentsV2.Web.Extensions +@using SFA.DAS.EmployerCommitmentsV2.Web.Models.Apprentice +@model SFA.DAS.EmployerCommitmentsV2.Web.Models.Apprentice.ChangeStatusRequestViewModel + +@{ + ViewBag.Title = "Which status change would you like to make?"; + ViewBag.Section = "apprentices"; + ViewBag.PageId = "change-apprentice-status"; +} + +
+
+ +

@ViewBag.Title

+ +

Pause an apprenticeship to:

+
    +
  • record a break in learning as agreed with the training provider
  • +
  • freeze future payments to a training provider for a period of time
  • +
+ +

Stop an apprenticeship to:

+
    +
  • change your training provider during the lifetime of a course
  • +
  • cancel all future payments
  • +
+ +
+ ! + + Warning + Do not stop completed apprenticeships. + +
+ +
+ @Html.AntiForgeryToken() + +
+
+ @if (!ViewData.ModelState.IsValid && ViewData.ModelState.ContainsKey(nameof(ChangeStatusRequestViewModel.SelectedStatusChange))) + { + + Error: @ViewData.ModelState[nameof(ChangeStatusRequestViewModel.SelectedStatusChange)].Errors.First().ErrorMessage + + } +
+ @if (Model.CurrentStatus == ApprenticeshipStatus.Paused) + { +
+ + +
+ } + else + { +
+ + +
+ } +
+ + +
+
+ + +
+
+
+
+ + +
+ +
+
+ +@section back { + Back +} diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Views/Apprentice/PauseApprenticeship.cshtml b/src/SFA.DAS.EmployerCommitmentsV2.Web/Views/Apprentice/PauseApprenticeship.cshtml new file mode 100644 index 000000000..514997497 --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Views/Apprentice/PauseApprenticeship.cshtml @@ -0,0 +1,93 @@ +@inject ILinkGenerator LinkGenerator +@using SFA.DAS.CommitmentsV2.Shared.Extensions +@using SFA.DAS.EmployerCommitmentsV2.Web.Models.Apprentice +@using SFA.DAS.EmployerCommitmentsV2.Web.Extensions +@model SFA.DAS.EmployerCommitmentsV2.Web.Models.Apprentice.PauseRequestViewModel + +@{ + string pageTitle; + string pageId; + string pageHeading; + + pageTitle = "Apprenticeship paused"; + pageId = "apprentice-paused"; + pageHeading = "Pause apprenticeship"; + + ViewBag.Title = pageTitle; + ViewBag.PageId = pageId; + ViewBag.Section = "apprentices"; +} + +
+
+ + + +
+ @Html.AntiForgeryToken() + +

@pageHeading

+ +

+ You’re about to pause this apprenticeship and all payments to the training provider. Any payments previously made to the training provider are unaffected. +

+ +

+ View your transactions to confirm all payments are up-to-date before pausing. +

+ +

You can return and resume the apprenticeship at any time.

+ +
+
+
Name
+
@Model.ApprenticeName
+
+
+
Unique learner number
+
@Model.ULN
+
+
+
Apprenticeship training course
+
@Model.Course
+
+
+
Date change takes effect
+
@Model.PauseDate.ToGdsFormat()
+
+ +
+ +
+
+ @if (!ViewData.ModelState.IsValid) + { + + Error: @ViewData.ModelState[nameof(PauseRequestViewModel.PauseConfirmed)].Errors.First().ErrorMessage + + }
+
+ + +
+
+ + +
+
+
+
+ + +
+ +
+
+ +@section back { + Back +} \ No newline at end of file diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Views/Apprentice/ResumeApprenticeship.cshtml b/src/SFA.DAS.EmployerCommitmentsV2.Web/Views/Apprentice/ResumeApprenticeship.cshtml new file mode 100644 index 000000000..0ee1f80db --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Views/Apprentice/ResumeApprenticeship.cshtml @@ -0,0 +1,88 @@ +@inject ILinkGenerator LinkGenerator +@using SFA.DAS.CommitmentsV2.Shared.Extensions +@using SFA.DAS.EmployerCommitmentsV2.Web.Models.Apprentice +@model SFA.DAS.EmployerCommitmentsV2.Web.Models.Apprentice.ResumeRequestViewModel + +@{ + string pageTitle; + string pageId; + string pageHeading; + + pageTitle = "Apprenticeship resumed"; + pageId = "apprentice-resumed"; + pageHeading = "Resume apprenticeship"; + + ViewBag.Title = pageTitle; + ViewBag.PageId = pageId; + ViewBag.Section = "apprentices"; +} + +
+
+ + + +
+ @Html.AntiForgeryToken() + +

@pageHeading

+ +

+ You’re about to resume this apprenticeship and any payments you've authorised to their training provider. +

+ +
+
+
Name
+
@Model.ApprenticeName
+
+
+
Unique learner number
+
@Model.ULN
+
+
+
Apprenticeship training course
+
@Model.Course
+
+
+
Pause date
+
@Model.PauseDate.GetValueOrDefault().ToGdsFormat()
+
+
+
Resume date
+
@Model.ResumeDate.ToGdsFormat()
+
+
+
+
+ @if (!ViewData.ModelState.IsValid) + { + + Error: @ViewData.ModelState[nameof(ResumeRequestViewModel.ResumeConfirmed)].Errors.First().ErrorMessage + + }
+
+ + +
+
+ + +
+
+
+
+ + +
+ +
+
+ +@section back { + Back +} \ No newline at end of file diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Views/Error/403.cshtml b/src/SFA.DAS.EmployerCommitmentsV2.Web/Views/Error/403.cshtml index b9e1d693a..0f5a3747e 100644 --- a/src/SFA.DAS.EmployerCommitmentsV2.Web/Views/Error/403.cshtml +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Views/Error/403.cshtml @@ -1,7 +1,18 @@ -@{ +@inject ILinkGenerator LinkGenerator +@using SFA.DAS.EmployerCommitmentsV2.Web.Extensions + +@{ ViewData["Title"] = "Access denied"; ViewBag.GaData.Vpv = "/error/403"; }

Access denied

-

Your account does not have sufficient privileges.

\ No newline at end of file +

Your account does not have sufficient privileges.

+ +
+
+

If you are experiencing difficulty accessing the area of the site you need, first contact an/the account owner to ensure you have the correct role assigned to your account.

+
+
+ +Go back to the service home page diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Views/Shared/_Layout.cshtml b/src/SFA.DAS.EmployerCommitmentsV2.Web/Views/Shared/_Layout.cshtml index 697d4efa8..209ccff5d 100644 --- a/src/SFA.DAS.EmployerCommitmentsV2.Web/Views/Shared/_Layout.cshtml +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Views/Shared/_Layout.cshtml @@ -1,9 +1,10 @@ @using SFA.DAS.Employer.Shared.UI.Models -@using SFA.DAS.EmployerCommitmentsV2.Web.Extensions + @{ + var accountHashedId = (string)ViewContext.RouteData.Values["accountHashedId"]; ViewBag.HideHeaderBorder = true; var footerModel = new FooterModel { AccountId = accountHashedId, UsePrivacyV2 = true }; @@ -58,8 +59,11 @@ - - + + @if (ViewBag.HideNav == null || !ViewBag.HideNav) + { + + }
@if (IsSectionDefined("Back")) @@ -72,7 +76,7 @@
- + diff --git a/src/SFA.DAS.EmployerCommitmentsV2/SFA.DAS.EmployerCommitmentsV2.csproj b/src/SFA.DAS.EmployerCommitmentsV2/SFA.DAS.EmployerCommitmentsV2.csproj index d01bfcb03..73cc55957 100644 --- a/src/SFA.DAS.EmployerCommitmentsV2/SFA.DAS.EmployerCommitmentsV2.csproj +++ b/src/SFA.DAS.EmployerCommitmentsV2/SFA.DAS.EmployerCommitmentsV2.csproj @@ -12,9 +12,9 @@ - - - + + +