public async Task FailsValidationIfEndDateOnPatternNotAfterStartDate()
        {
            CreateProfilePatternRequest request = NewOtherwiseValidCreateRequest(_ => _.FundingStreamPeriodEndDate = DateTime.MinValue);

            await WhenTheRequestIsValidated(request);

            ThenTheValidationResultsContainsTheErrors(("Pattern.FundingStreamPeriodEndDate", "Funding stream period end date must after funding stream period start date"));
        }
        public async Task FailsValidationIfNoFundingLineIdOnPattern()
        {
            CreateProfilePatternRequest request = NewOtherwiseValidCreateRequest(_ => _.FundingLineId = null);

            await WhenTheRequestIsValidated(request);

            ThenTheValidationResultsContainsTheErrors(("Pattern.FundingLineId", "You must provide a funding line id"));
        }
        public async Task FailsValidationIfNoStartDateOnPattern()
        {
            CreateProfilePatternRequest request = NewOtherwiseValidCreateRequest(_ => _.FundingStreamPeriodStartDate = DateTime.MinValue);

            await WhenTheRequestIsValidated(request);

            ThenTheValidationResultsContainsTheErrors(("Pattern.FundingStreamPeriodStartDate", "You must provide a funding stream period start date"));
        }
        private CreateProfilePatternRequest NewOtherwiseValidCreateRequest(Action <FundingStreamPeriodProfilePattern> overrides)
        {
            CreateProfilePatternRequest request = NewCreateRequest(_ => _.WithPattern(NewProfilePattern()));

            overrides(request.Pattern);

            return(request);
        }
        public async Task FailsValidationIfNoProfilePeriodsInPattern()
        {
            CreateProfilePatternRequest request = NewOtherwiseValidCreateRequest(_ => _.ProfilePattern = null);

            await WhenTheRequestIsValidated(request);

            ThenTheValidationResultsContainsTheErrors(("ProfilePattern", "The profile pattern must have at least one period"));
        }
        public async Task FailsValidationIfPatternWithSameKeyExists()
        {
            CreateProfilePatternRequest       request = NewCreateRequest(_ => _.WithPattern(NewProfilePattern()));
            FundingStreamPeriodProfilePattern pattern = request.Pattern;

            GivenTheExistingProfilePattern(pattern);

            await WhenTheRequestIsValidated(request);

            ThenTheValidationResultsContainsTheErrors(("Id", $"{pattern.Id} is already in use. Please choose a unique profile pattern id"));
        }
        public async Task CreateDelegatesToRepositoryIfPassesValidationAndSavesOk()
        {
            CreateProfilePatternRequest request = NewCreateRequest(_ =>
                                                                   _.WithPattern(NewProfilePattern()));

            GivenTheValidationResultForTheCreateRequest(request, NewValidationResult());
            AndTheStatusCodeForSavingTheProfilePattern(request.Pattern, HttpStatusCode.OK);

            OkResult result = await WhenTheProfilePatternIsCreated(request) as OkResult;

            result
            .Should()
            .NotBeNull();

            AndTheCacheWasInvalidated(request.Pattern.Id);
        }
        public async Task FailsValidationIfProfilePeriodsPercentagesDoNotTotal100()
        {
            CreateProfilePatternRequest request = NewOtherwiseValidCreateRequest(_ => _.ProfilePattern = NewPeriods(
                                                                                     NewPeriod(p => p.WithOccurrence(0)
                                                                                               .WithPercentage(50)
                                                                                               .WithPeriod("January")
                                                                                               .WithType(PeriodType.CalendarMonth)
                                                                                               .WithYear(2020)),
                                                                                     NewPeriod(p => p.WithOccurrence(1)
                                                                                               .WithPercentage(51)
                                                                                               .WithPeriod("January")
                                                                                               .WithType(PeriodType.CalendarMonth)
                                                                                               .WithYear(2020))));

            await WhenTheRequestIsValidated(request);

            ThenTheValidationResultsContainsTheErrors(("ProfilePattern", "The profile period percentages must total 100%"));
        }
        public async Task FailsValidationIfProfilePeriodsInPatternForUniquePeriods()
        {
            CreateProfilePatternRequest request = NewOtherwiseValidCreateRequest(_ => _.ProfilePattern = NewPeriods(
                                                                                     NewPeriod(p => p.WithOccurrence(1)
                                                                                               .WithPercentage(50)
                                                                                               .WithPeriod("January")
                                                                                               .WithType(PeriodType.CalendarMonth)
                                                                                               .WithYear(2020)),
                                                                                     NewPeriod(p => p.WithOccurrence(1)
                                                                                               .WithPercentage(50)
                                                                                               .WithPeriod("January")
                                                                                               .WithType(PeriodType.CalendarMonth)
                                                                                               .WithYear(2020))));

            await WhenTheRequestIsValidated(request);

            ThenTheValidationResultsContainsTheErrors(("ProfilePattern", "The profile periods must be for unique dates and occurence"));
        }
        public void CreateThrowsInvalidOperationExceptionIfSaveFails()
        {
            CreateProfilePatternRequest request = NewCreateRequest(_ =>
                                                                   _.WithPattern(NewProfilePattern()));
            HttpStatusCode invalidStatusCode = HttpStatusCode.Conflict;

            GivenTheValidationResultForTheCreateRequest(request, NewValidationResult());
            AndTheStatusCodeForSavingTheProfilePattern(request.Pattern, invalidStatusCode);

            Func <Task <IActionResult> > invocation = () => WhenTheProfilePatternIsCreated(request);

            invocation
            .Should()
            .Throw <InvalidOperationException>()
            .Which
            .Message
            .Should()
            .Be($"Unable to save profile pattern. StatusCode {invalidStatusCode}");

            AndTheCacheWasNotInvalidated();
        }
        public async Task CreateReturnsBadRequestIfRequestFailsValidation()
        {
            string invalidProperty = NewRandomString();
            string errorMessage    = NewRandomString();

            CreateProfilePatternRequest request = NewCreateRequest(_ =>
                                                                   _.WithPattern(NewProfilePattern()));

            ValidationResult expectedValidationResult = NewValidationResult(_ =>
                                                                            _.WithFailures(NewValidationFailure(vf => vf.WithPropertyName(invalidProperty)
                                                                                                                .WithErrorMessage(errorMessage))));

            GivenTheValidationResultForTheCreateRequest(request, expectedValidationResult);

            SerializableError serializableError = (await WhenTheProfilePatternIsCreated(request) as BadRequestObjectResult)?
                                                  .Value as SerializableError;

            serializableError?[invalidProperty]
            .Should()
            .BeEquivalentTo(new[] { errorMessage });

            AndNoProfilePatternsWereSaved();
            AndTheCacheWasNotInvalidated();
        }
        public async Task <HttpStatusCode> CreateProfilePattern(CreateProfilePatternRequest request)
        {
            Guard.ArgumentNotNull(request, nameof(request));

            return(await PostAsync("profiling/patterns", request));
        }
 private async Task <IActionResult> WhenTheProfilePatternIsCreated(CreateProfilePatternRequest request)
 {
     return(await _service.CreateProfilePattern(request));
 }
 private async Task WhenTheRequestIsValidated(CreateProfilePatternRequest request)
 {
     Result = await _validator.ValidateAsync(request);
 }
 public async Task <IActionResult> CreateProfilePattern([FromBody] CreateProfilePatternRequest request)
 {
     return(await _profilePatternService.CreateProfilePattern(request));
 }