Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
Expand Up @@ -871,28 +871,6 @@ public void SelfAssessmentOverview_Should_Return_View_With_Optional_Filter_Appli
result.Should().BeViewResult().ModelAs<SelfAssessmentOverviewViewModel>().CompetencyGroups.ToList()[0].Count().Should().Be(1);
}

[Test]
public void SelfAssessment_should_return_process_agreement_view_when_not_agreed_and_supervised()
{
// Given
var selfAssessment = SelfAssessmentTestHelper.CreateDefaultSelfAssessment();
selfAssessment.IsSupervised = true;
selfAssessment.SelfAssessmentProcessAgreed = false;
A.CallTo(() => selfAssessmentService.GetSelfAssessmentForCandidateById(DelegateUserId, SelfAssessmentId))
.Returns(selfAssessment);
A.CallTo(() => selfAssessmentService.GetAllSupervisorsForSelfAssessmentId(SelfAssessmentId, DelegateUserId))
.Returns(new List<SelfAssessmentSupervisor>());

// When
var result = controller.SelfAssessment(SelfAssessmentId);

// Then
result.Should().BeViewResult()
.WithViewName("SelfAssessments/AgreeSelfAssessmentProcess")
.Model.Should().BeOfType<SelfAssessmentProcessViewModel>()
.Which.SelfAssessmentID.Should().Be(SelfAssessmentId);
}

[Test]
public void SelfAssessment_should_return_description_view_when_process_agreed_or_not_supervised()
{
Expand Down Expand Up @@ -931,25 +909,25 @@ public void ProcessAgreed_should_return_agree_view_when_modelstate_invalid()
}

[Test]
public void ProcessAgreed_should_mark_progress_and_return_description_view()
public void ProcessAgreed_should_mark_progress_and_redirect_to_self_assessment()
{
// Given
var selfAssessment = SelfAssessmentTestHelper.CreateDefaultSelfAssessment();
var supervisors = new List<SelfAssessmentSupervisor>();
var model = new SelfAssessmentProcessViewModel { SelfAssessmentID = SelfAssessmentId };
A.CallTo(() => selfAssessmentService.GetSelfAssessmentForCandidateById(DelegateUserId, SelfAssessmentId))
.Returns(selfAssessment);
A.CallTo(() => selfAssessmentService.GetAllSupervisorsForSelfAssessmentId(SelfAssessmentId, DelegateUserId))
.Returns(supervisors);

// When
var result = controller.ProcessAgreed(model);

// Then
A.CallTo(() => selfAssessmentService.MarkProgressAgreed(SelfAssessmentId, DelegateUserId)).MustHaveHappened();
result.Should().BeViewResult()
.WithViewName("SelfAssessments/SelfAssessmentDescription")
.Model.Should().BeEquivalentTo(new SelfAssessmentDescriptionViewModel(selfAssessment, supervisors));
A.CallTo(() => selfAssessmentService.MarkProgressAgreed(SelfAssessmentId, DelegateUserId))
.MustHaveHappenedOnceExactly();

result.Should().BeRedirectToActionResult()
.WithActionName("SelfAssessment")
.WithRouteValue("selfAssessmentId", SelfAssessmentId);
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
using Microsoft.AspNetCore.Mvc.ViewEngines;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using System.IO;

[ServiceFilter(typeof(RequireProcessAgreementFilter))]
public partial class LearningPortalController
{
private const string CookieName = "DLSSelfAssessmentService";
Expand Down Expand Up @@ -68,17 +68,6 @@ public IActionResult SelfAssessment(int selfAssessmentId)
return RedirectToAction("StatusCode", "LearningSolutions", new { code = 403 });
}

if (!selfAssessment.SelfAssessmentProcessAgreed && selfAssessment.IsSupervised)
{
var processmodel = new SelfAssessmentProcessViewModel()
{
SelfAssessmentID = selfAssessmentId,
Vocabulary = selfAssessment.Vocabulary,
VocabPlural = FrameworkVocabularyHelper.VocabularyPlural(selfAssessment.Vocabulary)
};
return View("SelfAssessments/AgreeSelfAssessmentProcess", processmodel);
}

selfAssessmentService.IncrementLaunchCount(selfAssessmentId, delegateUserId);
selfAssessmentService.UpdateLastAccessed(selfAssessmentId, delegateUserId);
var supervisors = selfAssessmentService.GetAllSupervisorsForSelfAssessmentId(
Expand All @@ -90,7 +79,30 @@ public IActionResult SelfAssessment(int selfAssessmentId)
return View("SelfAssessments/SelfAssessmentDescription", model);
}

[HttpPost]
[Route("/LearningPortal/SelfAssessment/{selfAssessmentId:int}/AgreeProcess")]
public IActionResult AgreeSelfAssessmentProcess(int selfAssessmentId)
{
var delegateUserId = User.GetUserIdKnownNotNull();
var selfAssessment = selfAssessmentService.GetSelfAssessmentForCandidateById(delegateUserId, selfAssessmentId);

if (selfAssessment == null)
{
logger.LogWarning(
$"Attempt to display self assessment process for user {delegateUserId} with no self assessment"
);
return RedirectToAction("StatusCode", "LearningSolutions", new { code = 403 });
}

var processmodel = new SelfAssessmentProcessViewModel()
{
SelfAssessmentID = selfAssessmentId,
Vocabulary = selfAssessment.Vocabulary,
VocabPlural = FrameworkVocabularyHelper.VocabularyPlural(selfAssessment.Vocabulary)
};
return View("SelfAssessments/AgreeSelfAssessmentProcess", processmodel);
}

[HttpPost("/LearningPortal/SelfAssessment/{selfAssessmentId:int}/AgreeProcess")]
public IActionResult ProcessAgreed(SelfAssessmentProcessViewModel model)
{
if (!ModelState.IsValid)
Expand All @@ -107,13 +119,9 @@ public IActionResult ProcessAgreed(SelfAssessmentProcessViewModel model)
);
return RedirectToAction("StatusCode", "LearningSolutions", new { code = 403 });
}
var supervisors = selfAssessmentService.GetAllSupervisorsForSelfAssessmentId(
selfAssessmentId,
delegateUserId
).ToList();
var selfAssessmentDescriptionViewModel = new SelfAssessmentDescriptionViewModel(selfAssessment, supervisors);

selfAssessmentService.MarkProgressAgreed(selfAssessmentId, delegateUserId);
return View("SelfAssessments/SelfAssessmentDescription", selfAssessmentDescriptionViewModel);
return RedirectToAction("SelfAssessment", new { selfAssessmentId });

}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
namespace DigitalLearningSolutions.Web.ServiceFilter
{
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using DigitalLearningSolutions.Web.Services;
using DigitalLearningSolutions.Web.Helpers;
using Microsoft.Extensions.Logging;

public class RequireProcessAgreementFilter : IActionFilter
{
private readonly ISelfAssessmentService selfAssessmentService;
private readonly ILogger<RequireProcessAgreementFilter> logger;

public RequireProcessAgreementFilter(
ISelfAssessmentService selfAssessmentService,
ILogger<RequireProcessAgreementFilter> logger
)
{
this.selfAssessmentService = selfAssessmentService;
this.logger = logger;
}

public void OnActionExecuted(ActionExecutedContext context) { }

public void OnActionExecuting(ActionExecutingContext context)
{
if (!(context.Controller is Controller controller))
{
return;
}

if (!context.ActionArguments.ContainsKey("selfAssessmentId"))
{
return;
}

var selfAssessmentId = int.Parse(context.ActionArguments["selfAssessmentId"].ToString()!);
var delegateUserId = controller.User.GetUserIdKnownNotNull();

var selfAssessment = selfAssessmentService.GetSelfAssessmentForCandidateById(delegateUserId, selfAssessmentId);

if (selfAssessment == null)
{
logger.LogWarning(
$"Attempt to access self assessment {selfAssessmentId} by user {delegateUserId}, but no such assessment found"
);
context.Result = new RedirectToActionResult("StatusCode", "LearningSolutions", new { code = 403 });
return;
}

var actionName = context.RouteData.Values["action"]?.ToString();
if (actionName == "AgreeSelfAssessmentProcess" || actionName == "ProcessAgreed")
{
return;
}

if (!selfAssessment.SelfAssessmentProcessAgreed && selfAssessment.IsSupervised)
{
logger.LogInformation(
$"Redirecting user {delegateUserId} to agree process page for self assessment {selfAssessmentId}"
);

context.Result = new RedirectToActionResult(
"AgreeSelfAssessmentProcess",
"LearningPortal",
new { selfAssessmentId }
);
}
}
}
}
1 change: 1 addition & 0 deletions DigitalLearningSolutions.Web/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,7 @@ private static void RegisterWebServiceFilters(IServiceCollection services)
services.AddScoped<VerifyUserHasVerifiedPrimaryEmail>();
services.AddScoped<VerifyAdminAndDelegateUserCentre>();
services.AddScoped<IsCentreAuthorizedSelfAssessment>();
services.AddScoped<RequireProcessAgreementFilter>();
services.AddScoped<VerifyAdminUserCanAccessSelfAssessment>();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
<li>If you don’t fully meet the requirements, you can still document your progress and next steps for future assessment.</li>
</ol>

<form method="post" asp-controller="LearningPortal" asp-action="ProcessAgreed">
<form method="post" asp-controller="LearningPortal" asp-action="ProcessAgreed" asp-route-selfAssessmentId="@Model.SelfAssessmentID">
<div class="nhsuk-checkboxes__item">
<vc:single-checkbox asp-for="@nameof(Model.ActionConfirmed)"
label=" I understand and agree to the self-assessment process described above."
Expand Down
Loading