Skip to content

Commit

Permalink
Populate the MandatoryQualificationDeletedEvent
Browse files Browse the repository at this point in the history
  • Loading branch information
gunndabad committed Dec 15, 2023
1 parent 3c9ba06 commit 9d637dc
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,21 @@
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.RazorPages;
using TeachingRecordSystem.Core.Dqt.Queries;
using TeachingRecordSystem.Core.Events;
using TeachingRecordSystem.Core.Jobs.Scheduling;
using TeachingRecordSystem.Core.Services.Files;
using TeachingRecordSystem.Core.Services.TrsDataSync;

namespace TeachingRecordSystem.SupportUi.Pages.Mqs.DeleteMq;

[Journey(JourneyNames.DeleteMq), RequireJourneyInstance]
public class ConfirmModel(
ICrmQueryDispatcher crmQueryDispatcher,
TrsLinkGenerator linkGenerator,
IFileService fileService) : PageModel
IFileService fileService,
ReferenceDataCache referenceDataCache,
IClock clock,
IBackgroundJobScheduler backgroundJobScheduler) : PageModel
{
private static readonly TimeSpan _fileUrlExpiresAfter = TimeSpan.FromMinutes(15);

Expand Down Expand Up @@ -43,11 +49,40 @@ public class ConfirmModel(

public async Task<IActionResult> OnPost()
{
// Currently adding empty JSON until the deleted event is defined in a future Trello card
var qualification = (await crmQueryDispatcher.ExecuteQuery(new GetQualificationByIdQuery(QualificationId)))!;
var mqSpecialisms = await referenceDataCache.GetMqSpecialisms();

var deletedEvent = new MandatoryQualificationDeletedEvent()
{
EventId = Guid.NewGuid(),
CreatedUtc = clock.UtcNow,
RaisedBy = User.GetUserId(),
PersonId = PersonId!.Value,
MandatoryQualification = new()
{
QualificationId = QualificationId,
Specialism = mqSpecialisms.SingleOrDefault(s => s.Id == qualification.dfeta_MQ_SpecialismId?.Id)?.ToMandatoryQualificationSpecialism(),
Status = qualification.dfeta_MQ_Status?.ToMandatoryQualificationStatus(),
StartDate = qualification.dfeta_MQStartDate?.ToDateOnlyWithDqtBstFix(isLocalTime: true),
EndDate = qualification.dfeta_MQ_Date?.ToDateOnlyWithDqtBstFix(isLocalTime: true),
},
DeletionReason = DeletionReason!.GetDisplayName(),
DeletionReasonDetail = DeletionReasonDetail,
EvidenceFile = JourneyInstance!.State.EvidenceFileId is Guid fileId ?
new Core.Events.Models.File()
{
FileId = fileId,
Name = JourneyInstance.State.EvidenceFileName!
} :
null
};

await crmQueryDispatcher.ExecuteQuery(
new DeleteQualificationQuery(
QualificationId,
"{}"));
EventInfo.Create(deletedEvent).Serialize()));

await backgroundJobScheduler.Enqueue<TrsDataSyncHelper>(helper => helper.SyncMandatoryQualification(QualificationId, CancellationToken.None));

await JourneyInstance!.CompleteAsync();
TempData.SetFlashSuccess("Mandatory qualification deleted");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,15 @@
namespace TeachingRecordSystem.SupportUi.Pages.Mqs.DeleteMq;

[Journey(JourneyNames.DeleteMq), ActivatesJourney, RequireJourneyInstance]
public class IndexModel : PageModel
public class IndexModel(
ICrmQueryDispatcher crmQueryDispatcher,
ReferenceDataCache referenceDataCache,
TrsLinkGenerator linkGenerator,
IFileService fileService) : PageModel
{
public const int MaxFileSizeMb = 50;

private static readonly TimeSpan _fileUrlExpiresAfter = TimeSpan.FromMinutes(15);
private readonly ICrmQueryDispatcher _crmQueryDispatcher;
private readonly ReferenceDataCache _referenceDataCache;
private readonly TrsLinkGenerator _linkGenerator;
private readonly IFileService _fileService;

public IndexModel(
ICrmQueryDispatcher crmQueryDispatcher,
ReferenceDataCache referenceDataCache,
TrsLinkGenerator linkGenerator,
IFileService fileService)
{
_crmQueryDispatcher = crmQueryDispatcher;
_referenceDataCache = referenceDataCache;
_linkGenerator = linkGenerator;
_fileService = fileService;
}

public JourneyInstance<DeleteMqState>? JourneyInstance { get; set; }

Expand Down Expand Up @@ -82,7 +71,9 @@ public async Task OnGet()
{
DeletionReason ??= JourneyInstance!.State.DeletionReason;
DeletionReasonDetail ??= JourneyInstance?.State.DeletionReasonDetail;
UploadedEvidenceFileUrl ??= JourneyInstance?.State.EvidenceFileId is not null ? await _fileService.GetFileUrl(JourneyInstance.State.EvidenceFileId.Value, _fileUrlExpiresAfter) : null;
UploadedEvidenceFileUrl ??= JourneyInstance?.State.EvidenceFileId is not null ?
await fileService.GetFileUrl(JourneyInstance.State.EvidenceFileId.Value, _fileUrlExpiresAfter) :
null;
UploadEvidence ??= JourneyInstance?.State.UploadEvidence;
}

Expand All @@ -104,11 +95,11 @@ public async Task<IActionResult> OnPost()
{
if (EvidenceFileId is not null)
{
await _fileService.DeleteFile(EvidenceFileId.Value);
await fileService.DeleteFile(EvidenceFileId.Value);
}

using var stream = EvidenceFile.OpenReadStream();
var evidenceFileId = await _fileService.UploadFile(stream, EvidenceFile.ContentType);
var evidenceFileId = await fileService.UploadFile(stream, EvidenceFile.ContentType);
await JourneyInstance!.UpdateStateAsync(state =>
{
state.EvidenceFileId = evidenceFileId;
Expand All @@ -119,7 +110,7 @@ public async Task<IActionResult> OnPost()
}
else if (EvidenceFileId is not null)
{
await _fileService.DeleteFile(EvidenceFileId.Value);
await fileService.DeleteFile(EvidenceFileId.Value);
await JourneyInstance!.UpdateStateAsync(state =>
{
state.EvidenceFileId = null;
Expand All @@ -135,30 +126,30 @@ public async Task<IActionResult> OnPost()
state.UploadEvidence = UploadEvidence;
});

return Redirect(_linkGenerator.MqDeleteConfirm(QualificationId, JourneyInstance!.InstanceId));
return Redirect(linkGenerator.MqDeleteConfirm(QualificationId, JourneyInstance!.InstanceId));
}

public async Task<IActionResult> OnPostCancel()
{
if (JourneyInstance!.State.EvidenceFileId is not null)
{
await _fileService.DeleteFile(JourneyInstance!.State.EvidenceFileId.Value);
await fileService.DeleteFile(JourneyInstance!.State.EvidenceFileId.Value);
}

await JourneyInstance!.DeleteAsync();
return Redirect(_linkGenerator.PersonQualifications(PersonId!.Value));
return Redirect(linkGenerator.PersonQualifications(PersonId!.Value));
}

public override async Task OnPageHandlerExecutionAsync(PageHandlerExecutingContext context, PageHandlerExecutionDelegate next)
{
var qualification = await _crmQueryDispatcher.ExecuteQuery(new GetQualificationByIdQuery(QualificationId));
var qualification = await crmQueryDispatcher.ExecuteQuery(new GetQualificationByIdQuery(QualificationId));
if (qualification is null || qualification.dfeta_Type != dfeta_qualification_dfeta_Type.MandatoryQualification)
{
context.Result = NotFound();
return;
}

await JourneyInstance!.State.EnsureInitialized(_crmQueryDispatcher, _referenceDataCache, qualification);
await JourneyInstance!.State.EnsureInitialized(crmQueryDispatcher, referenceDataCache, qualification);

PersonId = JourneyInstance!.State.PersonId;
PersonName = JourneyInstance!.State.PersonName;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using FormFlow;
using Microsoft.EntityFrameworkCore;
using TeachingRecordSystem.Core.Dqt.Models;
using TeachingRecordSystem.Core.Events;
using TeachingRecordSystem.SupportUi.Pages.Mqs.DeleteMq;

namespace TeachingRecordSystem.SupportUi.Tests.PageTests.Mqs.DeleteMq;
Expand Down Expand Up @@ -141,28 +143,39 @@ public async Task Post_MissingDataInJourneyState_Redirects()
}

[Fact]
public async Task Post_Confirm_CompletesJourneyAndRedirectsWithFlashMessage()
public async Task Post_Confirm_DeletesMqCreatesEventCompletesJourneyAndRedirectsWithFlashMessage()
{
// Arrange
var person = await TestData.CreatePerson(b => b.WithMandatoryQualification());
var qualificationId = person.MandatoryQualifications!.First().QualificationId;
// Arrange
var mqEstablishment = "University of Leeds";
var specialism = MandatoryQualificationSpecialism.Hearing;
var status = MandatoryQualificationStatus.Passed;
var startDate = new DateOnly(2023, 09, 01);
var endDate = new DateOnly(2023, 11, 05);
var deletionReason = MqDeletionReasonOption.ProviderRequest;
var deletionReasonDetail = "Some details about the deletion reason";
var evidenceFileId = Guid.NewGuid();
var evidenceFileName = "test.pdf";

var person = await TestData.CreatePerson(b => b.WithMandatoryQualification(specialism: specialism, status: status, startDate: startDate, endDate: endDate));
var qualificationId = person.MandatoryQualifications!.Single().QualificationId;

var journeyInstance = await CreateJourneyInstance(
qualificationId,
new DeleteMqState()
{
Initialized = true,
PersonId = person.PersonId,
PersonName = person.Contact.ResolveFullName(includeMiddleName: false),
MqEstablishment = "University of Leeds",
Specialism = MandatoryQualificationSpecialism.Hearing,
Status = MandatoryQualificationStatus.Passed,
StartDate = new DateOnly(2023, 09, 01),
EndDate = new DateOnly(2023, 11, 05),
DeletionReason = MqDeletionReasonOption.ProviderRequest,
DeletionReasonDetail = "Some details about the deletion reason",
MqEstablishment = mqEstablishment,
Specialism = specialism,
Status = status,
StartDate = startDate,
EndDate = endDate,
DeletionReason = deletionReason,
DeletionReasonDetail = deletionReasonDetail,
UploadEvidence = true,
EvidenceFileId = Guid.NewGuid(),
EvidenceFileName = "test.pdf",
EvidenceFileId = evidenceFileId,
EvidenceFileName = evidenceFileName,
EvidenceFileSizeDescription = "1MB"
});

Expand All @@ -181,6 +194,42 @@ public async Task Post_Confirm_CompletesJourneyAndRedirectsWithFlashMessage()
var redirectDoc = await redirectResponse.GetDocument();
AssertEx.HtmlDocumentHasFlashSuccess(redirectDoc, "Mandatory qualification deleted");

await WithDbContext(async dbContext =>
{
var mq = await dbContext.MandatoryQualifications.IgnoreQueryFilters().SingleOrDefaultAsync(mq => mq.QualificationId == qualificationId);
Assert.NotNull(mq);
Assert.Equal(Clock.UtcNow, mq.DeletedOn);
});

EventObserver.AssertEventsSaved(e =>
{
var expectedMqDeletedEvent = new MandatoryQualificationDeletedEvent()
{
EventId = Guid.Empty,
CreatedUtc = Clock.UtcNow,
RaisedBy = GetCurrentUserId(),
PersonId = person.PersonId,
MandatoryQualification = new()
{
QualificationId = qualificationId,
Specialism = specialism,
Status = status,
StartDate = startDate,
EndDate = endDate
},
DeletionReason = deletionReason.GetDisplayName(),
DeletionReasonDetail = deletionReasonDetail,
EvidenceFile = new Core.Events.Models.File()
{
FileId = evidenceFileId,
Name = evidenceFileName
}
};

var actualMqDeletedEvent = Assert.IsType<MandatoryQualificationDeletedEvent>(e);
Assert.Equivalent(expectedMqDeletedEvent with { EventId = actualMqDeletedEvent.EventId }, actualMqDeletedEvent);
});

journeyInstance = await ReloadJourneyInstance(journeyInstance);
Assert.True(journeyInstance.Completed);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@ protected TestBase(HostFixture hostFixture)
});

_trsSyncSubscription = hostFixture.Services.GetRequiredService<TrsDataSyncHelper>().GetSyncedEntitiesObservable()
.Subscribe(onNext: (object[] synced) =>
.Subscribe(onNext: static (object[] synced) =>
{
var events = synced.OfType<EventBase>();
foreach (var e in events)
{
_testServices.EventObserver.OnEventSaved(e);
TestScopedServices.GetCurrent().EventObserver.OnEventSaved(e);
}
});
}
Expand Down

0 comments on commit 9d637dc

Please sign in to comment.