From 46d8a9516317b6820498cd9e3a77f911c4b9cd93 Mon Sep 17 00:00:00 2001 From: Daniel Bloxham Date: Thu, 30 Sep 2021 15:52:21 +0100 Subject: [PATCH 1/3] HEEDLS-603 - set up supervisor delegate relation when bulk uploading delegates --- .../DelegateUploadFileServiceTests.cs | 102 ++++++++++++++++++ .../SupervisorDelegateServiceTests.cs | 5 +- .../Services/DelegateUploadFileService.cs | 25 +++++ .../Services/SupervisorDelegateService.cs | 11 +- 4 files changed, 133 insertions(+), 10 deletions(-) diff --git a/DigitalLearningSolutions.Data.Tests/Services/DelegateUploadFileServiceTests.cs b/DigitalLearningSolutions.Data.Tests/Services/DelegateUploadFileServiceTests.cs index ecbc075793..cc9027c3d1 100644 --- a/DigitalLearningSolutions.Data.Tests/Services/DelegateUploadFileServiceTests.cs +++ b/DigitalLearningSolutions.Data.Tests/Services/DelegateUploadFileServiceTests.cs @@ -10,6 +10,7 @@ namespace DigitalLearningSolutions.Data.Tests.Services using DigitalLearningSolutions.Data.Exceptions; using DigitalLearningSolutions.Data.Models.DelegateUpload; using DigitalLearningSolutions.Data.Models.Register; + using DigitalLearningSolutions.Data.Models.Supervisor; using DigitalLearningSolutions.Data.Services; using DigitalLearningSolutions.Data.Tests.TestHelpers; using FakeItEasy; @@ -30,6 +31,7 @@ public class DelegateUploadFileServiceTests private DelegateUploadFileService delegateUploadFileService = null!; private IJobGroupsDataService jobGroupsDataService = null!; private IRegistrationDataService registrationDataService = null!; + private ISupervisorDelegateService supervisorDelegateService = null!; private IUserDataService userDataService = null!; private IUserService userService = null!; @@ -44,11 +46,13 @@ public void SetUp() userDataService = A.Fake(x => x.Strict()); userService = A.Fake(x => x.Strict()); registrationDataService = A.Fake(x => x.Strict()); + supervisorDelegateService = A.Fake(); delegateUploadFileService = new DelegateUploadFileService( jobGroupsDataService, userDataService, registrationDataService, + supervisorDelegateService, userService ); } @@ -618,6 +622,104 @@ public void ProcessDelegateTable_calls_register_with_expected_values_when_welcom result.RegisteredCount.Should().Be(1); } + [Test] + [TestCase("-4")] + [TestCase("-3")] + [TestCase("-2")] + [TestCase("-1")] + public void ProcessDelegateTable_unsuccessful_register_does_not_update_supervisor_delegates( + string failureStatusCode + ) + { + // Given + const string aliasId = "ALIAS"; + var row = GetSampleDelegateDataRow(candidateNumber: string.Empty, aliasId: aliasId); + var table = CreateTableFromData(new[] { row }); + + A.CallTo(() => userDataService.GetDelegateUserByAliasId(aliasId, CentreId)).Returns(null); + A.CallTo(() => userService.IsDelegateEmailValidForCentre("email@test.com", CentreId)).Returns(true); + A.CallTo(() => registrationDataService.RegisterDelegateByCentre(A._)) + .Returns(failureStatusCode); + + try + { + // When + delegateUploadFileService.ProcessDelegatesTable(table, CentreId); + } + catch (ArgumentOutOfRangeException ex) + { + // Then + ex.Message.Should().Be($"Unknown return value when creating delegate record. (Parameter 'status')\r\nActual value was {failureStatusCode}."); + ex.ActualValue.Should().Be(failureStatusCode); + } + finally + { + // Then + A.CallTo(() => registrationDataService.RegisterDelegateByCentre(A._)) + .MustHaveHappened(); + A.CallTo( + () => supervisorDelegateService.GetPendingSupervisorDelegateRecordsByEmailAndCentre( + A._, + A._ + ) + ).MustNotHaveHappened(); + A.CallTo( + () => supervisorDelegateService.AddDelegateIdToSupervisorDelegateRecords( + A>._, + A._ + ) + ).MustNotHaveHappened(); + } + } + + [Test] + public void ProcessDelegateTable_successful_register_updates_supervisor_delegates() + { + // Given + const string candidateNumber = "DELEGATE"; + const string aliasId = "ALIAS"; + const int newDelegateRecordId = 5; + var row = GetSampleDelegateDataRow(candidateNumber: string.Empty, aliasId: aliasId); + var table = CreateTableFromData(new[] { row }); + var supervisorDelegates = new List + { new SupervisorDelegate { ID = 1 }, new SupervisorDelegate { ID = 2 } }; + var supervisorDelegateIds = new List { 1, 2 }; + + A.CallTo(() => userDataService.GetDelegateUserByAliasId(aliasId, CentreId)).Returns(null); + A.CallTo(() => userService.IsDelegateEmailValidForCentre("email@test.com", CentreId)).Returns(true); + A.CallTo(() => registrationDataService.RegisterDelegateByCentre(A._)) + .Returns(candidateNumber); + A.CallTo(() => userDataService.GetDelegateUserByCandidateNumber(candidateNumber, CentreId)) + .Returns(UserTestHelper.GetDefaultDelegateUser(newDelegateRecordId)); + A.CallTo( + () => + supervisorDelegateService.GetPendingSupervisorDelegateRecordsByEmailAndCentre(A._, A._) + ).Returns(supervisorDelegates); + A.CallTo( + () => + supervisorDelegateService.AddDelegateIdToSupervisorDelegateRecords(A>._, A._) + ).DoesNothing(); + + // When + delegateUploadFileService.ProcessDelegatesTable(table, CentreId); + + // Then + A.CallTo(() => registrationDataService.RegisterDelegateByCentre(A._)) + .MustHaveHappened(); + A.CallTo( + () => supervisorDelegateService.GetPendingSupervisorDelegateRecordsByEmailAndCentre( + CentreId, + "email@test.com" + ) + ).MustHaveHappened(); + A.CallTo( + () => supervisorDelegateService.AddDelegateIdToSupervisorDelegateRecords( + A>.That.IsSameSequenceAs(supervisorDelegateIds), + newDelegateRecordId + ) + ).MustHaveHappened(); + } + [Test] public void ProcessDelegateTable_counts_updated_correctly() { diff --git a/DigitalLearningSolutions.Data.Tests/Services/SupervisorDelegateServiceTests.cs b/DigitalLearningSolutions.Data.Tests/Services/SupervisorDelegateServiceTests.cs index e3f3001b9c..445f85aac5 100644 --- a/DigitalLearningSolutions.Data.Tests/Services/SupervisorDelegateServiceTests.cs +++ b/DigitalLearningSolutions.Data.Tests/Services/SupervisorDelegateServiceTests.cs @@ -2,7 +2,6 @@ { using System; using DigitalLearningSolutions.Data.DataServices; - using DigitalLearningSolutions.Data.DataServices.UserDataService; using DigitalLearningSolutions.Data.Models.Supervisor; using DigitalLearningSolutions.Data.Services; using FakeItEasy; @@ -13,14 +12,12 @@ public class SupervisorDelegateServiceTests { private ISupervisorDelegateDataService supervisorDelegateDataService = null!; private ISupervisorDelegateService supervisorDelegateService = null!; - private IUserDataService userDataService = null!; [SetUp] public void SetUp() { supervisorDelegateDataService = A.Fake(); - userDataService = A.Fake(); - supervisorDelegateService = new SupervisorDelegateService(supervisorDelegateDataService, userDataService); + supervisorDelegateService = new SupervisorDelegateService(supervisorDelegateDataService); } [Test] diff --git a/DigitalLearningSolutions.Data/Services/DelegateUploadFileService.cs b/DigitalLearningSolutions.Data/Services/DelegateUploadFileService.cs index b74bda160d..9ddcdbe8b5 100644 --- a/DigitalLearningSolutions.Data/Services/DelegateUploadFileService.cs +++ b/DigitalLearningSolutions.Data/Services/DelegateUploadFileService.cs @@ -25,6 +25,7 @@ public class DelegateUploadFileService : IDelegateUploadFileService { private readonly IJobGroupsDataService jobGroupsDataService; private readonly IRegistrationDataService registrationDataService; + private readonly ISupervisorDelegateService supervisorDelegateService; private readonly IUserDataService userDataService; private readonly IUserService userService; @@ -32,11 +33,13 @@ public DelegateUploadFileService( IJobGroupsDataService jobGroupsDataService, IUserDataService userDataService, IRegistrationDataService registrationDataService, + ISupervisorDelegateService supervisorDelegateService, IUserService userService ) { this.userDataService = userDataService; this.registrationDataService = registrationDataService; + this.supervisorDelegateService = supervisorDelegateService; this.jobGroupsDataService = jobGroupsDataService; this.userService = userService; } @@ -199,11 +202,33 @@ private void RegisterDelegate(DelegateTableRow delegateRow, DateTime? welcomeEma "Unknown return value when creating delegate record." ); default: + SetUpSupervisorDelegateRelations(delegateRow.Email!, centreId, status); delegateRow.RowStatus = RowStatus.Registered; break; } } + private void SetUpSupervisorDelegateRelations(string emailAddress, int centreId, string candidateNumber) + { + var pendingSupervisorDelegateIds = + supervisorDelegateService.GetPendingSupervisorDelegateRecordsByEmailAndCentre( + centreId, + emailAddress + ).Select(supervisor => supervisor.ID).ToList(); + + if (!pendingSupervisorDelegateIds.Any()) + { + return; + } + + var newDelegateRecord = userDataService.GetDelegateUserByCandidateNumber(candidateNumber, centreId)!; + + supervisorDelegateService.AddDelegateIdToSupervisorDelegateRecords( + pendingSupervisorDelegateIds, + newDelegateRecord.Id + ); + } + private static bool ValidateHeaders(IXLTable table) { var expectedHeaders = new List diff --git a/DigitalLearningSolutions.Data/Services/SupervisorDelegateService.cs b/DigitalLearningSolutions.Data/Services/SupervisorDelegateService.cs index b7b66995ba..10f78d54c1 100644 --- a/DigitalLearningSolutions.Data/Services/SupervisorDelegateService.cs +++ b/DigitalLearningSolutions.Data/Services/SupervisorDelegateService.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; using DigitalLearningSolutions.Data.DataServices; - using DigitalLearningSolutions.Data.DataServices.UserDataService; using DigitalLearningSolutions.Data.Models.Supervisor; public interface ISupervisorDelegateService @@ -20,15 +19,12 @@ public interface ISupervisorDelegateService public class SupervisorDelegateService : ISupervisorDelegateService { private readonly ISupervisorDelegateDataService supervisorDelegateDataService; - private readonly IUserDataService userDataService; public SupervisorDelegateService( - ISupervisorDelegateDataService supervisorDelegateDataService, - IUserDataService userDataService + ISupervisorDelegateDataService supervisorDelegateDataService ) { this.supervisorDelegateDataService = supervisorDelegateDataService; - this.userDataService = userDataService; } public SupervisorDelegate? GetSupervisorDelegateRecordByInviteHash(Guid inviteHash) @@ -36,7 +32,10 @@ IUserDataService userDataService return supervisorDelegateDataService.GetSupervisorDelegateRecordByInviteHash(inviteHash); } - public IEnumerable GetPendingSupervisorDelegateRecordsByEmailAndCentre(int centreId, string email) + public IEnumerable GetPendingSupervisorDelegateRecordsByEmailAndCentre( + int centreId, + string email + ) { return supervisorDelegateDataService.GetPendingSupervisorDelegateRecordsByEmailAndCentre(centreId, email); } From 0af6dbef1b73f8d74b2756ea47c09da8e046bee9 Mon Sep 17 00:00:00 2001 From: Daniel Bloxham Date: Wed, 6 Oct 2021 15:52:22 +0100 Subject: [PATCH 2/3] HEEDLS-603 - move delegate call --- .../Services/DelegateUploadFileServiceTests.cs | 6 +++++- .../Services/DelegateUploadFileService.cs | 17 ++++++++--------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/DigitalLearningSolutions.Data.Tests/Services/DelegateUploadFileServiceTests.cs b/DigitalLearningSolutions.Data.Tests/Services/DelegateUploadFileServiceTests.cs index cc9027c3d1..58efb4bcde 100644 --- a/DigitalLearningSolutions.Data.Tests/Services/DelegateUploadFileServiceTests.cs +++ b/DigitalLearningSolutions.Data.Tests/Services/DelegateUploadFileServiceTests.cs @@ -48,6 +48,10 @@ public void SetUp() registrationDataService = A.Fake(x => x.Strict()); supervisorDelegateService = A.Fake(); + A.CallTo(() => userDataService.GetDelegateUserByCandidateNumber(A._, A._)) + .Returns(UserTestHelper.GetDefaultDelegateUser()); + + delegateUploadFileService = new DelegateUploadFileService( jobGroupsDataService, userDataService, @@ -649,7 +653,7 @@ string failureStatusCode catch (ArgumentOutOfRangeException ex) { // Then - ex.Message.Should().Be($"Unknown return value when creating delegate record. (Parameter 'status')\r\nActual value was {failureStatusCode}."); + ex.Message.Should().Be($"Unknown return value when creating delegate record. (Parameter 'statusOrCandidateNumber')\r\nActual value was {failureStatusCode}."); ex.ActualValue.Should().Be(failureStatusCode); } finally diff --git a/DigitalLearningSolutions.Data/Services/DelegateUploadFileService.cs b/DigitalLearningSolutions.Data/Services/DelegateUploadFileService.cs index 9ddcdbe8b5..29bc753afc 100644 --- a/DigitalLearningSolutions.Data/Services/DelegateUploadFileService.cs +++ b/DigitalLearningSolutions.Data/Services/DelegateUploadFileService.cs @@ -187,8 +187,8 @@ private void UpdateDelegate(DelegateTableRow delegateRow, DelegateUser delegateU private void RegisterDelegate(DelegateTableRow delegateRow, DateTime? welcomeEmailDate, int centreId) { var model = new DelegateRegistrationModel(delegateRow, centreId, welcomeEmailDate); - var status = registrationDataService.RegisterDelegateByCentre(model); - switch (status) + var statusOrCandidateNumber = registrationDataService.RegisterDelegateByCentre(model); + switch (statusOrCandidateNumber) { case "-1": delegateRow.Error = BulkUploadResult.ErrorReason.UnexpectedErrorForCreate; @@ -197,18 +197,19 @@ private void RegisterDelegate(DelegateTableRow delegateRow, DateTime? welcomeEma case "-3": case "-4": throw new ArgumentOutOfRangeException( - nameof(status), - status, + nameof(statusOrCandidateNumber), + statusOrCandidateNumber, "Unknown return value when creating delegate record." ); default: - SetUpSupervisorDelegateRelations(delegateRow.Email!, centreId, status); + var newDelegateRecord = userDataService.GetDelegateUserByCandidateNumber(statusOrCandidateNumber, centreId)!; + SetUpSupervisorDelegateRelations(delegateRow.Email!, centreId, newDelegateRecord.Id); delegateRow.RowStatus = RowStatus.Registered; break; } } - private void SetUpSupervisorDelegateRelations(string emailAddress, int centreId, string candidateNumber) + private void SetUpSupervisorDelegateRelations(string emailAddress, int centreId, int delegateId) { var pendingSupervisorDelegateIds = supervisorDelegateService.GetPendingSupervisorDelegateRecordsByEmailAndCentre( @@ -221,11 +222,9 @@ private void SetUpSupervisorDelegateRelations(string emailAddress, int centreId, return; } - var newDelegateRecord = userDataService.GetDelegateUserByCandidateNumber(candidateNumber, centreId)!; - supervisorDelegateService.AddDelegateIdToSupervisorDelegateRecords( pendingSupervisorDelegateIds, - newDelegateRecord.Id + delegateId ); } From 9856045902a2c6fcf09c49965b136f86c1d5ee9e Mon Sep 17 00:00:00 2001 From: Daniel Bloxham Date: Fri, 8 Oct 2021 12:52:57 +0100 Subject: [PATCH 3/3] HEEDLS-603 - rename status to errorCode --- .../Services/DelegateUploadFileServiceTests.cs | 2 +- .../Services/DelegateUploadFileService.cs | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/DigitalLearningSolutions.Data.Tests/Services/DelegateUploadFileServiceTests.cs b/DigitalLearningSolutions.Data.Tests/Services/DelegateUploadFileServiceTests.cs index 58efb4bcde..088c15d26f 100644 --- a/DigitalLearningSolutions.Data.Tests/Services/DelegateUploadFileServiceTests.cs +++ b/DigitalLearningSolutions.Data.Tests/Services/DelegateUploadFileServiceTests.cs @@ -653,7 +653,7 @@ string failureStatusCode catch (ArgumentOutOfRangeException ex) { // Then - ex.Message.Should().Be($"Unknown return value when creating delegate record. (Parameter 'statusOrCandidateNumber')\r\nActual value was {failureStatusCode}."); + ex.Message.Should().Be($"Unknown return value when creating delegate record. (Parameter 'errorCodeOrCandidateNumber')\r\nActual value was {failureStatusCode}."); ex.ActualValue.Should().Be(failureStatusCode); } finally diff --git a/DigitalLearningSolutions.Data/Services/DelegateUploadFileService.cs b/DigitalLearningSolutions.Data/Services/DelegateUploadFileService.cs index 29bc753afc..ee99285e94 100644 --- a/DigitalLearningSolutions.Data/Services/DelegateUploadFileService.cs +++ b/DigitalLearningSolutions.Data/Services/DelegateUploadFileService.cs @@ -187,8 +187,8 @@ private void UpdateDelegate(DelegateTableRow delegateRow, DelegateUser delegateU private void RegisterDelegate(DelegateTableRow delegateRow, DateTime? welcomeEmailDate, int centreId) { var model = new DelegateRegistrationModel(delegateRow, centreId, welcomeEmailDate); - var statusOrCandidateNumber = registrationDataService.RegisterDelegateByCentre(model); - switch (statusOrCandidateNumber) + var errorCodeOrCandidateNumber = registrationDataService.RegisterDelegateByCentre(model); + switch (errorCodeOrCandidateNumber) { case "-1": delegateRow.Error = BulkUploadResult.ErrorReason.UnexpectedErrorForCreate; @@ -197,12 +197,12 @@ private void RegisterDelegate(DelegateTableRow delegateRow, DateTime? welcomeEma case "-3": case "-4": throw new ArgumentOutOfRangeException( - nameof(statusOrCandidateNumber), - statusOrCandidateNumber, + nameof(errorCodeOrCandidateNumber), + errorCodeOrCandidateNumber, "Unknown return value when creating delegate record." ); default: - var newDelegateRecord = userDataService.GetDelegateUserByCandidateNumber(statusOrCandidateNumber, centreId)!; + var newDelegateRecord = userDataService.GetDelegateUserByCandidateNumber(errorCodeOrCandidateNumber, centreId)!; SetUpSupervisorDelegateRelations(delegateRow.Email!, centreId, newDelegateRecord.Id); delegateRow.RowStatus = RowStatus.Registered; break;