public async Task ShouldCallReservationValidationsAndReturnErrors() { var viewModel = new ApprenticeshipViewModel(); viewModel.ReservationId = Guid.NewGuid(); viewModel.StartDate = new DateTimeViewModel(1, 1, 2001); var updateModel = new UpdateApprenticeshipViewModel(); MockMediator.Setup(m => m.SendAsync(It.IsAny <GetReservationValidationRequest>())) .ReturnsAsync(new GetReservationValidationResponse { Data = new ReservationValidationResult(new List <ReservationValidationError> { new ReservationValidationError("Reservation", "A reservation issue") }) }); var result = await Orchestrator.ValidateApprenticeship(viewModel, updateModel); Assert.IsTrue(result.ContainsKey("Reservation")); Assert.AreEqual("A reservation issue", result["Reservation"]); MockMediator.Verify(m => m.SendAsync(It.IsAny <GetReservationValidationRequest>()), Times.Once); }
private bool NeedReapproval(UpdateApprenticeshipViewModel model) { return (!string.IsNullOrEmpty(model.FirstName) || !string.IsNullOrEmpty(model.LastName) || model.DateOfBirth?.DateTime != null || !string.IsNullOrEmpty(model.TrainingCode) || model.StartDate?.DateTime != null || model.EndDate?.DateTime != null || !string.IsNullOrEmpty(model.Cost)); }
public async Task CreateApprenticeshipUpdate(UpdateApprenticeshipViewModel apprenticeship, string hashedAccountId, string userId, string userName, string userEmail) { var employerId = _hashingService.DecodeValue(hashedAccountId); await _mediator.SendAsync(new CreateApprenticeshipUpdateCommand { EmployerId = employerId, ApprenticeshipUpdate = _apprenticeshipMapper.MapFrom(apprenticeship), UserId = userId, UserEmailAddress = userEmail, UserDisplayName = userName }); }
public void ThenTheCookieIsDeletedBeforeBeingCreated() { //Arrange var model = new UpdateApprenticeshipViewModel(); //Act _orchestrator.CreateApprenticeshipViewModelCookie(model); //Assert _cookieStorageService.Verify(x => x.Delete(CookieName)); _cookieStorageService.Verify(x => x.Create(model, CookieName, 1)); }
private bool AnyChanges(UpdateApprenticeshipViewModel data) { return (!string.IsNullOrEmpty(data.FirstName) || !string.IsNullOrEmpty(data.LastName) || data.DateOfBirth != null || !string.IsNullOrEmpty(data.TrainingName) || data.StartDate != null || data.EndDate != null || data.Cost != null || data.EmployerRef != null); }
public Dictionary <string, string> ValidateAcademicYear(UpdateApprenticeshipViewModel model) { var dict = new Dictionary <string, string>(); if (model.StartDate?.DateTime != null && _academicYearValidator.Validate(model.StartDate.DateTime.Value) == AcademicYearValidationResult.NotWithinFundingPeriod) { dict.Add($"{nameof(model.StartDate)}", ValidationText.AcademicYearStartDate01.Text); } return(dict); }
public async Task ShouldValidateOverlapAndDateChecks() { var viewModel = new ApprenticeshipViewModel(); var updateModel = new UpdateApprenticeshipViewModel(); await Orchestrator.ValidateApprenticeship(viewModel, updateModel); MockMediator.Verify(m => m.SendAsync(It.IsAny <GetOverlappingApprenticeshipsQueryRequest>()), Times.Once, failMessage: "Should call"); _mockValidator.Verify(m => m.MapOverlappingErrors(It.IsAny <GetOverlappingApprenticeshipsQueryResponse>()), Times.Once, failMessage: "Should verify overlapping apprenticeship"); _mockValidator.Verify(m => m.ValidateToDictionary(It.IsAny <ApprenticeshipViewModel>()), Times.Once, failMessage: "Should validate apprenticeship"); _mockValidator.Verify(m => m.ValidateAcademicYear(It.IsAny <UpdateApprenticeshipViewModel>()), Times.Once, failMessage: "Should validate academic year"); }
public async Task <UpdateApprenticeshipViewModel> CompareAndMapToApprenticeshipViewModel( Apprenticeship original, ApprenticeshipViewModel edited) { string ChangedOrNull(string a, string edit) => a?.Trim() == edit?.Trim() ? null : edit; var apprenticeshipDetailsViewModel = MapToApprenticeshipDetailsViewModel(original); var model = new UpdateApprenticeshipViewModel { FirstName = ChangedOrNull(original.FirstName, edited.FirstName), LastName = ChangedOrNull(original.LastName, edited.LastName), DateOfBirth = original.DateOfBirth == edited.DateOfBirth.DateTime ? null : edited.DateOfBirth, Cost = original.Cost == edited.Cost.AsNullableDecimal() ? null : edited.Cost, StartDate = original.StartDate == edited.StartDate.DateTime ? null : edited.StartDate, EndDate = original.EndDate == edited.EndDate.DateTime ? null : edited.EndDate, EmployerRef = original.EmployerRef?.Trim() == edited.EmployerRef?.Trim() || (string.IsNullOrEmpty(original.EmployerRef) && string.IsNullOrEmpty(edited.EmployerRef)) ? null : edited.EmployerRef ?? "", OriginalApprenticeship = apprenticeshipDetailsViewModel }; if (!string.IsNullOrWhiteSpace(edited.TrainingCode) && original.TrainingCode != edited.TrainingCode) { var training = await GetTrainingProgramme(edited.TrainingCode); if (training != null) { model.TrainingType = int.TryParse(training.CourseCode, out _) ? TrainingType.Standard : TrainingType.Framework; model.TrainingCode = edited.TrainingCode; model.TrainingName = training.Name; } else { model.TrainingType = edited.TrainingType; model.TrainingCode = edited.TrainingCode; model.TrainingName = edited.TrainingName; _logger.Warn($"Apprentice training course has expired. TrainingName: {edited.TrainingName}, TrainingCode: {edited.TrainingCode}, Employer Ref: {edited.EmployerRef}, Apprenticeship ULN: {edited.ULN}"); } } model.HasHadDataLockSuccess = original.HasHadDataLockSuccess; return(model); }
public async Task ShouldValidateDateButNotCallReservationValidationsBecauseStartDateIsBlank() { var viewModel = new ApprenticeshipViewModel(); viewModel.ReservationId = Guid.NewGuid(); var updateModel = new UpdateApprenticeshipViewModel(); _mockValidator.Setup(m => m.ValidateAcademicYear(It.Is <UpdateApprenticeshipViewModel>(p => p.StartDate == null))) .Returns(new Dictionary <string, string> { { "StartDate", "Start Date cannot be empty" } }); var result = await Orchestrator.ValidateApprenticeship(viewModel, updateModel); Assert.IsTrue(result.ContainsKey("StartDate")); Assert.AreEqual("Start Date cannot be empty", result["StartDate"]); MockMediator.Verify(m => m.SendAsync(It.IsAny <GetReservationValidationRequest>()), Times.Never); }
public ApprenticeshipUpdate MapFrom(UpdateApprenticeshipViewModel viewModel) { var apprenticeshipId = _hashingService.DecodeValue(viewModel.HashedApprenticeshipId); return(new ApprenticeshipUpdate { ApprenticeshipId = apprenticeshipId, Cost = viewModel.Cost.AsNullableDecimal(), DateOfBirth = viewModel.DateOfBirth?.DateTime, FirstName = viewModel.FirstName, LastName = viewModel.LastName, StartDate = viewModel.StartDate?.DateTime, EndDate = viewModel.EndDate?.DateTime, Originator = Originator.Employer, Status = ApprenticeshipUpdateStatus.Pending, TrainingName = viewModel.TrainingName, TrainingCode = viewModel.TrainingCode, TrainingType = viewModel.TrainingType, EmployerRef = viewModel.EmployerRef }); }
public async Task <UpdateApprenticeshipViewModel> CompareAndMapToApprenticeshipViewModel( Apprenticeship original, ApprenticeshipViewModel edited) { Func <string, string, string> changedOrNull = (a, edit) => a?.Trim() == edit?.Trim() ? null : edit; var apprenticeshipDetailsViewModel = MapToApprenticeshipDetailsViewModel(original); var model = new UpdateApprenticeshipViewModel { FirstName = changedOrNull(original.FirstName, edited.FirstName), LastName = changedOrNull(original.LastName, edited.LastName), DateOfBirth = original.DateOfBirth == edited.DateOfBirth.DateTime ? null : edited.DateOfBirth, Cost = original.Cost == edited.Cost.AsNullableDecimal() ? null : edited.Cost, StartDate = original.StartDate == edited.StartDate.DateTime ? null : edited.StartDate, EndDate = original.EndDate == edited.EndDate.DateTime ? null : edited.EndDate, EmployerRef = original.EmployerRef?.Trim() == edited.EmployerRef?.Trim() || (string.IsNullOrEmpty(original.EmployerRef) && string.IsNullOrEmpty(edited.EmployerRef)) ? null : edited.EmployerRef ?? "", OriginalApprenticeship = apprenticeshipDetailsViewModel }; if (!string.IsNullOrWhiteSpace(edited.TrainingCode) && original.TrainingCode != edited.TrainingCode) { var training = await GetTrainingProgramme(edited.TrainingCode); model.TrainingType = training is Standard ? TrainingType.Standard : TrainingType.Framework; model.TrainingCode = edited.TrainingCode; model.TrainingName = training.Title; } return(model); }
public async Task <IDictionary <string, string> > ValidateApprenticeship(ApprenticeshipViewModel apprenticeship, UpdateApprenticeshipViewModel updatedModel) { ConcurrentDictionary <string, string> errors = new ConcurrentDictionary <string, string>(); await Task.WhenAll(AddOverlapAndDateValidationErrors(errors, apprenticeship, updatedModel), AddReservationValidationErrors(errors, apprenticeship)); return(errors); }
public async Task <ActionResult> ViewChanges(string hashedAccountId, string hashedApprenticeshipId, UpdateApprenticeshipViewModel apprenticeship) { if (!ModelState.IsValid) { var viewmodel = await _orchestrator .GetViewChangesViewModel(hashedAccountId, hashedApprenticeshipId, OwinWrapper.GetClaimValue(@"sub")); viewmodel.Data.AddErrorsFromModelState(ModelState); SetErrorMessage(viewmodel, viewmodel.Data.ErrorDictionary); return(View(viewmodel)); } if (apprenticeship.ChangesConfirmed != null && apprenticeship.ChangesConfirmed.Value) { await _orchestrator.SubmitUndoApprenticeshipUpdate(hashedAccountId, hashedApprenticeshipId, OwinWrapper.GetClaimValue(@"sub"), OwinWrapper.GetClaimValue(DasClaimTypes.DisplayName), OwinWrapper.GetClaimValue(DasClaimTypes.Email)); SetOkayMessage("Changes undone"); } return(RedirectToAction("Details")); }
public async Task <ActionResult> ReviewChanges(string hashedAccountId, string hashedApprenticeshipId, UpdateApprenticeshipViewModel viewModel) { if (!ModelState.IsValid) { var viewmodel = await _orchestrator .GetViewChangesViewModel(hashedAccountId, hashedApprenticeshipId, OwinWrapper.GetClaimValue(@"sub")); viewmodel.Data.AddErrorsFromModelState(ModelState); viewModel.ApprenticeDetailsV2Link = _linkGenerator.CommitmentsV2Link($"{hashedAccountId}/apprentices/{hashedApprenticeshipId}/details"); SetErrorMessage(viewmodel, viewmodel.Data.ErrorDictionary); return(View(viewmodel)); } if (viewModel.ChangesConfirmed != null) { await _orchestrator.SubmitReviewApprenticeshipUpdate(hashedAccountId, hashedApprenticeshipId, OwinWrapper.GetClaimValue(@"sub"), viewModel.ChangesConfirmed.Value, OwinWrapper.GetClaimValue(DasClaimTypes.DisplayName), OwinWrapper.GetClaimValue(DasClaimTypes.Email)); var message = viewModel.ChangesConfirmed.Value ? "Changes approved" : "Changes rejected"; SetOkayMessage(message); } return(RedirectToAction("Details", new { hashedAccountId, hashedApprenticeshipId })); }
public async Task <ActionResult> SubmitChanges(string hashedAccountId, string hashedApprenticeshipId, UpdateApprenticeshipViewModel apprenticeship) { if (!await IsUserRoleAuthorized(hashedAccountId, Role.Owner, Role.Transactor)) { return(View("AccessDenied")); } var orginalApp = await _orchestrator.GetApprenticeship(hashedAccountId, hashedApprenticeshipId, OwinWrapper.GetClaimValue(@"sub")); apprenticeship.OriginalApprenticeship = orginalApp.Data; if (!ModelState.IsValid) { var viewmodel = await _orchestrator.GetOrchestratorResponseUpdateApprenticeshipViewModelFromCookie(hashedAccountId, hashedApprenticeshipId); viewmodel.Data.AddErrorsFromModelState(ModelState); SetErrorMessage(viewmodel, viewmodel.Data.ErrorDictionary); return(View("ConfirmChanges", viewmodel)); } if (apprenticeship.ChangesConfirmed != null && !apprenticeship.ChangesConfirmed.Value) { return(RedirectToAction("Details", new { hashedAccountId, hashedApprenticeshipId })); } await _orchestrator.CreateApprenticeshipUpdate(apprenticeship, hashedAccountId, OwinWrapper.GetClaimValue(@"sub"), OwinWrapper.GetClaimValue(DasClaimTypes.DisplayName), OwinWrapper.GetClaimValue(DasClaimTypes.Email)); var message = NeedReapproval(apprenticeship) ? "Suggested changes sent to training provider for approval, where needed." : "Apprentice updated"; var flashmessage = new FlashMessageViewModel { Message = message, Severity = FlashMessageSeverityLevel.Okay }; AddFlashMessageToCookie(flashmessage); return(RedirectToAction("Details", new { hashedAccountId, hashedApprenticeshipId })); }
private async Task AddOverlapAndDateValidationErrors(ConcurrentDictionary <string, string> errors, ApprenticeshipViewModel apprenticeship, UpdateApprenticeshipViewModel updatedModel) { void AddToErrors(IDictionary <string, string> items) { foreach (var error in items) { errors.TryAdd(error.Key, error.Value); } } var overlappingErrors = await Mediator.SendAsync( new GetOverlappingApprenticeshipsQueryRequest { Apprenticeship = new List <Apprenticeship> { await _apprenticeshipMapper.MapFrom(apprenticeship) } }); AddToErrors(_approvedApprenticeshipValidator.MapOverlappingErrors(overlappingErrors)); AddToErrors(_approvedApprenticeshipValidator.ValidateToDictionary(apprenticeship)); AddToErrors(_approvedApprenticeshipValidator.ValidateAcademicYear(updatedModel)); }
public void CreateApprenticeshipViewModelCookie(UpdateApprenticeshipViewModel model) { _apprenticshipsViewModelCookieStorageService.Delete(CookieName); model.OriginalApprenticeship = null; _apprenticshipsViewModelCookieStorageService.Create(model, CookieName); }