예제 #1
0
        public async Task WhenPostingVacancyReadyForReReviewMessage_ThenItShouldPostAMessageWithTheNewIconAndSuitableMessage()
        {
            var vacancyReference = 1000000001;
            var vacancyReview    = new VacancyReview {
                VacancyReference = vacancyReference, SubmissionCount = 2
            };
            var mockSlackClient = new Mock <ISlackClient>();

            mockSlackClient
            .Setup(c => c.Post(
                       It.Is <SlackMessage>(s =>
                                            s.Text.Contains("ready for review") &&
                                            s.Text.Contains(" (2nd submission)") &&
                                            s.Text.Contains(vacancyReference.ToString())
                                            ),
                       It.Is <Emojis>(e => e.Equals(Emojis.New))))
            .Returns(Task.CompletedTask)
            .Verifiable();

            var client = new SlackNotifyVacancyReviewUpdates(mockSlackClient.Object);

            await client.VacancyReviewCreated(vacancyReview);

            mockSlackClient.Verify();
        }
        public async Task WhenPostingVacancyApprovedFromFirstReviewMessage_ThenItShouldPostAMessageWithTheNewIconAndSuitableMessage()
        {
            var vacancyReference = 1000000001;
            var vacancyReview    = new VacancyReview {
                VacancyReference = vacancyReference, SubmissionCount = 1, VacancySnapshot = new Vacancy {
                    OwnerType = OwnerType.Employer
                }
            };
            var mockSlackClient = new Mock <ISlackClient>();

            mockSlackClient
            .Setup(c => c.PostAsync(
                       It.Is <SlackMessage>(s =>
                                            s.Text.Contains("has been approved") &&
                                            !s.Text.Contains(" (1st review)") &&
                                            s.Text.Contains(" (Employer)") &&
                                            s.Text.Contains(vacancyReference.ToString())),
                       It.Is <SlackVacancyNotificationType>(e => e.Equals(SlackVacancyNotificationType.Approved))))
            .Returns(Task.CompletedTask)
            .Verifiable();

            var client = new SlackNotifyVacancyReviewUpdates(mockSlackClient.Object, Options.Create(new SlackConfiguration()));

            await client.VacancyReviewApproved(vacancyReview);

            mockSlackClient.Verify();
        }
예제 #3
0
        private List <AutomatedQaResultViewModel> GetAutomatedQaResultViewModel(VacancyReview review)
        {
            var vm = new List <AutomatedQaResultViewModel>();

            if (review.AutomatedQaOutcomeIndicators == null || review.AutomatedQaOutcome == null)
            {
                return(vm);
            }

            var referredOutcomes = review.AutomatedQaOutcomeIndicators
                                   .Where(i => i.IsReferred)
                                   .Select(i => i.RuleOutcomeId)
                                   .ToList();

            foreach (var ruleOutcome in review.AutomatedQaOutcome.RuleOutcomes)
            {
                vm.AddRange(
                    ruleOutcome.Details
                    .Where(d => referredOutcomes.Contains(d.Id))
                    .Select(d => new AutomatedQaResultViewModel
                {
                    OutcomeId = d.Id.ToString(),
                    FieldId   = d.Target,
                    Checked   = true,
                    Text      = _ruleTemplateRunner.ToText(ruleOutcome.RuleId, d.Data, FieldDisplayNameResolver.Resolve(d.Target))
                }));
            }

            //sort by the order of the fields on the review page
            return(vm.OrderBy(v => ReviewFields.Keys.ToList().FindIndex(k => k == v.FieldId)).ToList());
        }
        public Task CreateAsync(VacancyReview vacancy)
        {
            var collection = GetCollection <VacancyReview>();

            return(RetryPolicy.ExecuteAsync(_ =>
                                            collection.InsertOneAsync(vacancy),
                                            new Context(nameof(CreateAsync))));
        }
예제 #5
0
        public Task UpdateAsync(VacancyReview review)
        {
            var filterBuilder = Builders <VacancyReview> .Filter;
            var filter        = filterBuilder.Eq(v => v.Id, review.Id) & filterBuilder.Eq(v => v.VacancyReference, review.VacancyReference);
            var collection    = GetCollection <VacancyReview>();

            return(RetryPolicy.ExecuteAsync(context => collection.ReplaceOneAsync(filter, review), new Context(nameof(UpdateAsync))));
        }
예제 #6
0
 private Task ClosePendingReview(VacancyReview review)
 {
     _logger.LogInformation($"Closing pending review {review.Id} as the provider is blocked");
     review.ManualOutcome = ManualQaOutcome.Blocked;
     review.Status = ReviewStatus.Closed;
     review.ClosedDate = _timeProvider.Now;
     return _vacancyReviewRepository.UpdateAsync(review);
 }
        private async Task EnsureUserIsAssignedAsync(VacancyReview review, string userId)
        {
            var userReviews = await _vacancyClient.GetAssignedVacancyReviewsForUserAsync(userId);

            if (userReviews.Any(r => r.Id == review.Id) == false)
            {
                throw new UnassignedVacancyReviewException($"You have been unassigned from {review.VacancyReference}");
            }
        }
        private void Validate(VacancyReview review)
        {
            var validationResult = _vacancyReviewValidator.Validate(review);

            if (!validationResult.IsValid)
            {
                throw new ValidationException(validationResult.Errors);
            }
        }
        private static void ValidateReviewStateForViewing(VacancyReview review)
        {
            if (review.Status != ReviewStatus.PendingReview && review.Status != ReviewStatus.UnderReview)
            {
                throw new InvalidStateException($"Review is not in a correct state for viewing. State: {review.Status}");
            }

            if (review.VacancySnapshot == null)
            {
                throw new NotFoundException($"Vacancy snapshot is null for review with id: {review.Id}");
            }
        }
        public async Task WhenPostingVacancyReferredMessage_ThenItShouldPostAMessageWithTheNewIconAndSuitableMessage()
        {
            var vacancyReference = 1000000001;

            var manualQaFieldIndicators = new List <ManualQaFieldIndicator>
            {
                new ManualQaFieldIndicator {
                    FieldIdentifier = "field1", IsChangeRequested = true
                },
                new ManualQaFieldIndicator {
                    FieldIdentifier = "field2", IsChangeRequested = false
                }
            };

            var automatedQaOutcomeIndicators = new List <RuleOutcomeIndicator>
            {
                new RuleOutcomeIndicator {
                    RuleOutcomeId = Guid.NewGuid(), IsReferred = true
                },
                new RuleOutcomeIndicator {
                    RuleOutcomeId = Guid.NewGuid(), IsReferred = false
                }
            };

            var vacancyReview = new VacancyReview
            {
                VacancyReference             = vacancyReference,
                ManualQaFieldIndicators      = manualQaFieldIndicators,
                AutomatedQaOutcomeIndicators = automatedQaOutcomeIndicators,
                VacancySnapshot = new Vacancy {
                    OwnerType = OwnerType.Employer
                }
            };

            var mockSlackClient = new Mock <ISlackClient>();

            mockSlackClient
            .Setup(c => c.PostAsync(
                       It.Is <SlackMessage>(s =>
                                            s.Text.Contains("has been referred") &&
                                            s.Text.Contains(" (2 issues)") &&
                                            s.Text.Contains(" (Employer)") &&
                                            s.Text.Contains(vacancyReference.ToString())),
                       It.Is <SlackVacancyNotificationType>(e => e.Equals(SlackVacancyNotificationType.Referred))))
            .Returns(Task.CompletedTask)
            .Verifiable();

            var client = new SlackNotifyVacancyReviewUpdates(mockSlackClient.Object, Options.Create(new SlackConfiguration()));

            await client.VacancyReviewReferred(vacancyReview);

            mockSlackClient.Verify();
        }
예제 #11
0
        public void ApplicationReviewShouldBeValid(string manualQaComment)
        {
            var m = new VacancyReview
            {
                ManualQaComment = manualQaComment
            };

            var validator = new VacancyReviewValidator();

            var result = validator.Validate(m);

            result.IsValid.Should().BeTrue();
        }
예제 #12
0
        public Task VacancyReviewCreated(VacancyReview vacancyReview)
        {
            var messageBody = $"Vacancy VAC{vacancyReview.VacancyReference} is ready for review";

            if (vacancyReview.SubmissionCount > 1)
            {
                messageBody += $" ({GetNumericSuffix(vacancyReview.SubmissionCount)} submission)";
            }

            var message = new SlackMessage {
                Text = messageBody
            };

            return(_slackClient.Post(message, Emojis.New));
        }
        private async Task <ClosureReason?> TryGetReasonToCloseVacancy(VacancyReview review, Vacancy vacancy)
        {
            if (HasVacancyBeenTransferredSinceReviewWasCreated(review, vacancy))
            {
                return(vacancy.TransferInfo.Reason == TransferReason.EmployerRevokedPermission ?
                       ClosureReason.TransferredByEmployer : ClosureReason.TransferredByQa);
            }

            if (await HasProviderBeenBlockedSinceReviewWasCreatedAsync(vacancy))
            {
                return(ClosureReason.BlockedByQa);
            }

            return(null);
        }
        public Task VacancyReviewCreated(VacancyReview vacancyReview)
        {
            var messageBody = $"Vacancy VAC{vacancyReview.VacancyReference} is ready for review ({vacancyReview.VacancySnapshot.OwnerType.ToString()})";

            if (vacancyReview.SubmissionCount > 1)
            {
                messageBody += $" ({GetNumericSuffix(vacancyReview.SubmissionCount)} submission)";
            }

            var message = new SlackMessage {
                Text = messageBody
            };

            return(_slackClient.PostAsync(message, SlackVacancyNotificationType.New));
        }
예제 #15
0
        public void ShouldValidateManaulQaComment(string manualQaComment, string expectedErrorMessage)
        {
            var m = new VacancyReview
            {
                ManualQaComment = manualQaComment
            };

            var validator = new VacancyReviewValidator();

            var result = validator.Validate(m);

            result.IsValid.Should().BeFalse();
            result.Errors.Count.Should().Be(1);
            result.Errors[0].ErrorMessage.Should().Be(expectedErrorMessage);
        }
        public Task VacancyReviewApproved(VacancyReview vacancyReview)
        {
            var messageBody = string.Format("Vacancy <{0}{1}|VAC{1}> has been approved ({2})", _findAnApprenticeshipDetailPrefixUrl, vacancyReview.VacancyReference, vacancyReview.VacancySnapshot.OwnerType.ToString());

            if (vacancyReview.SubmissionCount > 1)
            {
                messageBody += $" ({GetNumericSuffix(vacancyReview.SubmissionCount)} review)";
            }

            var message = new SlackMessage {
                Text = messageBody
            };

            return(_slackClient.PostAsync(message, SlackVacancyNotificationType.Approved));
        }
예제 #17
0
        public Task VacancyReviewApproved(VacancyReview vacancyReview)
        {
            var messageBody = $"Vacancy VAC{vacancyReview.VacancyReference} has been approved";

            if (vacancyReview.SubmissionCount > 1)
            {
                messageBody += $" ({GetNumericSuffix(vacancyReview.SubmissionCount)} review)";
            }

            var message = new SlackMessage {
                Text = messageBody
            };

            return(_slackClient.Post(message, Emojis.Approved));
        }
예제 #18
0
        private VacancyReview BuildNewReview(Vacancy vacancy, int previousReviewCount, DateTime slaDeadline, List <string> updatedFieldIdentifiers)
        {
            var review = new VacancyReview
            {
                VacancyReference        = vacancy.VacancyReference.Value,
                Title                   = vacancy.Title,
                Status                  = ReviewStatus.New,
                CreatedDate             = _time.Now,
                SubmittedByUser         = vacancy.SubmittedByUser,
                SubmissionCount         = previousReviewCount + 1,
                SlaDeadline             = slaDeadline,
                VacancySnapshot         = vacancy,
                UpdatedFieldIdentifiers = updatedFieldIdentifiers
            };

            return(review);
        }
예제 #19
0
        private ReviewSummaryViewModel ConvertToReviewSummaryViewModel(
            ReviewFieldMappingLookupsForPage reviewFieldIndicatorsForPage, VacancyReview review)
        {
            if (review != null)
            {
                var fieldIndicators =
                    _fieldMappingsLookup.MapFromFieldIndicators(reviewFieldIndicatorsForPage, review).ToList();

                return(new ReviewSummaryViewModel
                {
                    HasBeenReviewed = true,
                    ReviewerComments = review.ManualQaComment,
                    FieldIndicators = fieldIndicators
                });
            }

            return(new ReviewSummaryViewModel());
        }
예제 #20
0
        private VacancyReviewSearchResultViewModel MapToViewModel(VacancyReview vacancyReview, VacancyUser vacancyUser)
        {
            var isAvailableForReview =
                _vacancyClient.VacancyReviewCanBeAssigned(vacancyReview.Status, vacancyReview.ReviewedDate);

            return(new VacancyReviewSearchResultViewModel
            {
                IsAssignedToLoggedInUser = vacancyUser.UserId == vacancyReview.ReviewedByUser?.UserId,
                AssignedTo = vacancyReview.ReviewedByUser?.Name,
                AssignedTimeElapsed = vacancyReview.ReviewedDate.GetShortTimeElapsed(_timeProvider.Now),
                ClosingDate = vacancyReview.VacancySnapshot.ClosingDate.GetValueOrDefault(),
                EmployerName = vacancyReview.VacancySnapshot.EmployerName,
                VacancyReference = vacancyReview.VacancyReference.ToString(),
                VacancyTitle = vacancyReview.Title,
                ReviewId = vacancyReview.Id,
                IsClosed = vacancyReview.Status == ReviewStatus.Closed,
                SubmittedDate = vacancyReview.VacancySnapshot.SubmittedDate.GetValueOrDefault(),
                IsAvailableForReview = isAvailableForReview
            });
        }
        public Task VacancyReviewReferred(VacancyReview vacancyReview)
        {
            var messageBody = $"Vacancy VAC{vacancyReview.VacancyReference} has been referred ({vacancyReview.VacancySnapshot.OwnerType.ToString()})";

            var issueCount = vacancyReview.ManualQaFieldIndicators.Count(i => i.IsChangeRequested) +
                             vacancyReview.AutomatedQaOutcomeIndicators.Count(i => i.IsReferred);

            if (issueCount == 1)
            {
                messageBody += $" ({issueCount} issue)";
            }
            if (issueCount > 1)
            {
                messageBody += $" ({issueCount} issues)";
            }

            var message = new SlackMessage {
                Text = messageBody
            };

            return(_slackClient.PostAsync(message, SlackVacancyNotificationType.Referred));
        }
예제 #22
0
        public Task VacancyReviewReferred(VacancyReview vacancyReview)
        {
            var messageBody = $"Vacancy VAC{vacancyReview.VacancyReference} has been referred";

            var issueCount = vacancyReview.ManualQaFieldIndicators.Count(i => i.IsChangeRequested) +
                             vacancyReview.AutomatedQaOutcomeIndicators.Count(i => i.IsReferred);

            if (issueCount == 1)
            {
                messageBody += $" ({issueCount} issue)";
            }
            if (issueCount > 1)
            {
                messageBody += $" ({issueCount} issues)";
            }

            var message = new SlackMessage {
                Text = messageBody
            };

            return(_slackClient.Post(message, Emojis.Referred));
        }
예제 #23
0
        public async Task WhenPostingVacancyApprovedFromFirstReviewMessage_ThenItShouldPostAMessageWithTheNewIconAndSuitableMessage()
        {
            var vacancyReference = 1000000001;
            var vacancyReview    = new VacancyReview {
                VacancyReference = vacancyReference, SubmissionCount = 1
            };
            var mockSlackClient = new Mock <ISlackClient>();

            mockSlackClient
            .Setup(c => c.Post(
                       It.Is <SlackMessage>(s =>
                                            s.Text.Contains("has been approved") &&
                                            !s.Text.Contains(" (1st review)") &&
                                            s.Text.Contains(vacancyReference.ToString())),
                       It.Is <Emojis>(e => e.Equals(Emojis.Approved))))
            .Returns(Task.CompletedTask)
            .Verifiable();

            var client = new SlackNotifyVacancyReviewUpdates(mockSlackClient.Object);

            await client.VacancyReviewApproved(vacancyReview);

            mockSlackClient.Verify();
        }
예제 #24
0
        public async Task <ReviewViewModel> Map(VacancyReview review)
        {
            var vacancy = review.VacancySnapshot;

            var currentVacancy = _vacancyClient.GetVacancyAsync(review.VacancyReference);

            var programmeTask = _vacancyClient.GetApprenticeshipProgrammeAsync(vacancy.ProgrammeId);

            var reviewHistoryTask = _vacancyClient.GetVacancyReviewHistoryAsync(review.VacancyReference);

            var approvedCountTask = _vacancyClient.GetApprovedCountAsync(vacancy.SubmittedByUser.UserId);

            var approvedFirstTimeCountTask = _vacancyClient.GetApprovedFirstTimeCountAsync(vacancy.SubmittedByUser.UserId);

            var reviewSummaryTask = _reviewSummaryService.GetReviewSummaryViewModelAsync(review.Id,
                                                                                         ReviewFieldMappingLookups.GetPreviewReviewFieldIndicators());

            var anonymousApprovedCountTask = vacancy.IsAnonymous ? _vacancyClient.GetAnonymousApprovedCountAsync(vacancy.LegalEntityId) : Task.FromResult(0);

            await Task.WhenAll(
                currentVacancy, programmeTask,
                approvedCountTask,
                approvedFirstTimeCountTask,
                reviewHistoryTask,
                reviewSummaryTask,
                anonymousApprovedCountTask);

            var programme = programmeTask.Result;

            var currentVacancyResult = currentVacancy.Result;

            var historiesVm = GetReviewHistoriesViewModel(reviewHistoryTask.Result);

            var vm = new ReviewViewModel();

            vm.Review = reviewSummaryTask.Result;
            try
            {
                vm.SubmittedByName         = vacancy.SubmittedByUser.Name;
                vm.SubmittedByEmail        = vacancy.SubmittedByUser.Email;
                vm.ApplicationInstructions = vacancy.ApplicationInstructions;
                vm.ApplicationMethod       = vacancy.ApplicationMethod.Value;
                vm.ApplicationUrl          = vacancy.ApplicationUrl;
                vm.ClosingDate             = vacancy.ClosingDate?.AsGdsDate();
                vm.EducationLevelName      =
                    EducationLevelNumberHelper.GetEducationLevelNameOrDefault(programme.EducationLevelNumber, programme.Level);
                vm.EmployerContactName      = vacancy.EmployerContact?.Name;
                vm.EmployerContactEmail     = vacancy.EmployerContact?.Email;
                vm.EmployerContactTelephone = vacancy.EmployerContact?.Phone;
                vm.EmployerDescription      = vacancy.EmployerDescription;
                vm.EmployerName             = vacancy.EmployerName;
                vm.EmployerNameOption       = vacancy.EmployerNameOption.Value;
                vm.AnonymousReason          = vacancy.AnonymousReason;
                vm.AnonymousApprovedCount   = anonymousApprovedCountTask.Result;
                vm.EmployerWebsiteUrl       = vacancy.EmployerWebsiteUrl;
                vm.MapUrl = MapImageHelper.GetEmployerLocationMapUrl(vacancy, _mapService, MapImageWidth, MapImageHeight);
                vm.EmployerAddressElements  = vacancy.EmployerAddressForDisplay();
                vm.LegalEntityName          = vacancy.LegalEntityName;
                vm.IsDisabilityConfident    = vacancy.IsDisabilityConfident;
                vm.NumberOfPositionsCaption = $"{"position".ToQuantity(vacancy.NumberOfPositions.Value)} available";
                vm.OutcomeDescription       = vacancy.OutcomeDescription;
                vm.PossibleStartDate        = vacancy.StartDate?.AsGdsDate();
                vm.ProviderContactName      = vacancy.ProviderContact?.Name;
                vm.ProviderContactEmail     = vacancy.ProviderContact?.Email;
                vm.ProviderContactTelephone = vacancy.ProviderContact?.Phone;
                vm.ProviderName             = vacancy.TrainingProvider.Name;
                vm.Qualifications           = vacancy.Qualifications.SortQualifications(_qualifications.Value).AsText();
                vm.ShortDescription         = vacancy.ShortDescription;
                vm.Skills                 = vacancy.Skills ?? Enumerable.Empty <string>();
                vm.OwnerType              = vacancy.OwnerType;
                vm.ThingsToConsider       = vacancy.ThingsToConsider;
                vm.Title                  = vacancy.Title;
                vm.TrainingDescription    = vacancy.TrainingDescription;
                vm.VacancyDescription     = vacancy.Description;
                vm.VacancyReferenceNumber = $"VAC{vacancy.VacancyReference}";
                vm.TrainingTitle          = programme.Title;
                vm.TrainingType           = programme.ApprenticeshipType.GetDisplayName();
                vm.TrainingLevel          = programme.Level.GetDisplayName();
                vm.Level                  = programme.Level;
                vm.ExpectedDuration       = (vacancy.Wage.DurationUnit.HasValue && vacancy.Wage.Duration.HasValue)
                    ? vacancy.Wage.DurationUnit.Value.GetDisplayName().ToQuantity(vacancy.Wage.Duration.Value)
                    : null;
                vm.HoursPerWeek = $"{vacancy.Wage.WeeklyHours:0.##}";
                vm.WageInfo     = vacancy.Wage.WageAdditionalInformation;
                vm.WageText     = vacancy.StartDate.HasValue
                    ? vacancy.Wage.ToText(vacancy.StartDate)
                    : null;
                vm.WorkingWeekDescription               = vacancy.Wage.WorkingWeekDescription;
                vm.SubmittedDate                        = vacancy.SubmittedDate.Value;
                vm.VacancyReviewsApprovedCount          = approvedCountTask.Result;
                vm.VacancyReviewsApprovedFirstTimeCount = approvedFirstTimeCountTask.Result;

                vm.FieldIdentifiers = await GetFieldIdentifiersViewModel(review);

                vm.ReviewerComment = review.ManualQaComment;
                vm.ReviewHistories = historiesVm;
                vm.IsResubmission  = review.SubmissionCount > 1;

                vm.ReviewerName = review.ReviewedByUser.Name;
                vm.ReviewedDate = review.ReviewedDate.GetValueOrDefault();

                vm.ManualOutcome = review.ManualOutcome;

                if (review.Status == ReviewStatus.Closed)
                {
                    vm.PageTitle = GetPageTitle(historiesVm, review.Id, review.ManualOutcome, currentVacancyResult);
                }

                vm.AutomatedQaResults = GetAutomatedQaResultViewModel(review);
                vm.IsVacancyDeleted   = currentVacancyResult.IsDeleted;
            }
            catch (NullReferenceException ex)
            {
                _logger.LogError(ex, "Unable to map vacancy to view model. Unexpected null fields.");
                throw;
            }

            return(vm);
        }
예제 #25
0
        private async Task <IEnumerable <FieldIdentifierViewModel> > GetFieldIdentifiersViewModel(VacancyReview currentReview)
        {
            var vm = GetFieldIndicators();

            if (currentReview.SubmissionCount <= 1)
            {
                return(vm);
            }

            var previousReview = await _vacancyClient.GetCurrentReferredVacancyReviewAsync(currentReview.VacancyReference);

            if (previousReview == null)
            {
                return(vm);
            }

            //translate field name to FieldIdentifier (a single field can have multiple field identifiers)
            var updatedFieldIdentifiers = currentReview.UpdatedFieldIdentifiers?
                                          .SelectMany(f => ReviewFields[f])
                                          .Distinct()
                                          .ToList() ?? new List <string>();

            foreach (var field in vm)
            {
                var hasChanged = updatedFieldIdentifiers.Contains(field.FieldIdentifier);

                var previouslyChecked = previousReview.ManualQaFieldIndicators.Any(m => m.FieldIdentifier == field.FieldIdentifier &&
                                                                                   m.IsChangeRequested);

                field.FieldValueHasChanged = hasChanged;
                field.Checked = previouslyChecked;
            }

            return(vm);
        }
예제 #26
0
 public bool VacancyReviewCanBeAssigned(VacancyReview review)
 {
     return(VacancyReviewCanBeAssigned(review.Status, review.ReviewedDate));
 }
 private Task PublishVacancyReviewApprovedEventAsync(ApproveVacancyReviewCommand message, VacancyReview review)
 {
     return(_messaging.PublishEvent(new VacancyReviewApprovedEvent
     {
         ReviewId = message.ReviewId,
         VacancyReference = review.VacancyReference
     }));
 }
 private bool HasVacancyBeenTransferredSinceReviewWasCreated(VacancyReview review, Vacancy vacancy)
 {
     return(review.VacancySnapshot.TransferInfo == null && vacancy.TransferInfo != null);
 }
        public IEnumerable <ReviewFieldIndicatorViewModel> MapFromFieldIndicators(ReviewFieldMappingLookupsForPage pageMappings, VacancyReview review)
        {
            var manualQaFieldIdentifierNames = review.ManualQaFieldIndicators
                                               ?.Where(r => r.IsChangeRequested)
                                               .Select(r => r.FieldIdentifier)
                                               .ToList() ?? new List <string>();

            var autoQaReferredOutcomeIds = review.AutomatedQaOutcomeIndicators
                                           ?.Where(i => i.IsReferred)
                                           .Select(i => i.RuleOutcomeId)
                                           .ToList() ?? new List <Guid>();

            var autoQaReferredOutcomes = review.AutomatedQaOutcome?.RuleOutcomes
                                         .SelectMany(d => d.Details)
                                         .Where(x => autoQaReferredOutcomeIds.Contains(x.Id))
                                         .ToList() ?? new List <RuleOutcome>();

            var uniqueFieldIdentifierNames =
                manualQaFieldIdentifierNames.Union(
                    autoQaReferredOutcomes.SelectMany(x => pageMappings.VacancyPropertyMappingsLookup.TryGetValue(x.Target, out var value) ? value : Enumerable.Empty <string>()));

            var indicatorsToDisplayLookup = pageMappings.FieldIdentifiersForPage
                                            .Where(r => uniqueFieldIdentifierNames.Contains(r.ReviewFieldIdentifier))
                                            .ToDictionary(x => x.ReviewFieldIdentifier, y => y);

            foreach (var indicator in indicatorsToDisplayLookup)
            {
                if (manualQaFieldIdentifierNames.Contains(indicator.Key))
                {
                    indicator.Value.ManualQaText = ManualQaMessages[indicator.Key];
                }

                var autoQaOutcomes = autoQaReferredOutcomes.Where(x => pageMappings.VacancyPropertyMappingsLookup.TryGetValue(x.Target, out var value) && value.Contains(indicator.Key))
                                     .Select(x => _ruleTemplateRunner.ToText(x.RuleId, x.Data, FieldDisplayNameResolver.Resolve(x.Target)));

                indicator.Value.AutoQaTexts.AddRange(autoQaOutcomes);
            }

            return(indicatorsToDisplayLookup.Values);
        }
예제 #30
0
        public void ShouldMap()
        {
            var shortDescriptionProfanityCheckRuleOutcome =
                new RuleOutcome(
                    RuleId.ProfanityChecks,
                    100,
                    "Profanity 'drat' found in 'ShortDescription'",
                    "ShortDescription",
                    new List <RuleOutcome>(), "{\"Profanity\" : \"drat\",\"Occurrences\" : 1}");

            var titleProfanityCheckRuleOutcome = new RuleOutcome(
                RuleId.ProfanityChecks,
                0,
                "No profanities found in 'Title'",
                "Title");

            var profanityChecksRuleOutcome = new RuleOutcome(
                RuleId.ProfanityChecks,
                100,
                "No profanities found in 'Title', Profanity 'drat' found in 'ShortDescription', etc",
                "",
                new List <RuleOutcome>
            {
                shortDescriptionProfanityCheckRuleOutcome,
                titleProfanityCheckRuleOutcome
            }
                );

            var sut = new ReviewFieldIndicatorMapper(new RuleMessageTemplateRunner());

            var review = new VacancyReview
            {
                ManualQaFieldIndicators = new List <ManualQaFieldIndicator>
                {
                    new ManualQaFieldIndicator
                    {
                        IsChangeRequested = false,
                        FieldIdentifier   = FieldIdentifiers.Title
                    },
                    new ManualQaFieldIndicator
                    {
                        IsChangeRequested = true,
                        FieldIdentifier   = FieldIdentifiers.ShortDescription
                    }
                },
                AutomatedQaOutcomeIndicators = new List <RuleOutcomeIndicator>
                {
                    new RuleOutcomeIndicator
                    {
                        IsReferred    = false,
                        RuleOutcomeId = titleProfanityCheckRuleOutcome.Id
                    },
                    new RuleOutcomeIndicator
                    {
                        IsReferred    = true,
                        RuleOutcomeId = shortDescriptionProfanityCheckRuleOutcome.Id
                    }
                },
                AutomatedQaOutcome = new RuleSetOutcome {
                    RuleOutcomes = new List <RuleOutcome> {
                        profanityChecksRuleOutcome
                    }
                }
            };

            var vm = sut.MapFromFieldIndicators(ReviewFieldMappingLookups.GetPreviewReviewFieldIndicators(), review).ToList();

            vm.Count.Should().Be(1);

            var shortDescription = vm.Single(v => v.ReviewFieldIdentifier == FieldIdentifiers.ShortDescription);

            shortDescription.ManualQaText.Should().NotBeNullOrEmpty();

            shortDescription.AutoQaTexts.Count.Should().Be(1);
            shortDescription.AutoQaTexts[0].Should().Be("Brief overview contains the phrase 'drat'");
        }