コード例 #1
0
        public static async Task CreateOrderItemAsync_ValidationFailure_AddsModelErrors(
            [Frozen] IReadOnlyList <ErrorDetails> errorDetails,
            AggregateValidationResult aggregateValidationResult,
            [Frozen] Mock <ICreateOrderItemService> createOrderItemService,
            [Frozen] Mock <IOrderItemService> orderItemService,
            [Frozen] CallOffId callOffId,
            CatalogueItemId catalogueItemId,
            Order order,
            CreateOrderItemModel model,
            OrderItemsController controller)
        {
            controller.ProblemDetailsFactory = new TestProblemDetailsFactory();
            aggregateValidationResult.AddValidationResult(new ValidationResult(errorDetails), 0);

            Expression <Func <ICreateOrderItemService, Task <AggregateValidationResult> > > createAsync = s => s.CreateAsync(
                It.Is <Order>(o => o.Equals(order)),
                It.Is <CatalogueItemId>(i => i == catalogueItemId),
                It.Is <CreateOrderItemModel>(m => m == model));

            orderItemService.Setup(o => o.GetOrder(callOffId)).ReturnsAsync(order);
            createOrderItemService.Setup(createAsync).ReturnsAsync(aggregateValidationResult);

            await controller.CreateOrderItemAsync(callOffId, catalogueItemId, model);

            var modelState = controller.ModelState;

            modelState.ErrorCount.Should().Be(errorDetails.Count);
            modelState.Keys.Should().BeEquivalentTo(errorDetails.Select(e => e.ParentName + "[0]." + e.Field));

            var modelStateErrors = modelState.Values.Select(v => v.Errors[0].ErrorMessage);

            modelStateErrors.Should().BeEquivalentTo(errorDetails.Select(e => e.Id));
        }
コード例 #2
0
        public static async Task CreateOrderItemsAsync_ValidationFailure_ReturnsExpectedResponse(
            ErrorDetails errorDetails,
            AggregateValidationResult aggregateValidationResult,
            [Frozen] Mock <ICreateOrderItemService> createOrderItemService,
            [Frozen] Mock <IOrderItemService> orderItemService,
            [Frozen] CallOffId callOffId,
            CatalogueItemId catalogueItemId,
            Order order,
            CreateOrderItemModel model,
            OrderItemsController controller)
        {
            controller.ProblemDetailsFactory = new TestProblemDetailsFactory();
            aggregateValidationResult.AddValidationResult(new ValidationResult(errorDetails), 0);

            Expression <Func <ICreateOrderItemService, Task <AggregateValidationResult> > > createAsync = s => s.CreateAsync(
                It.Is <Order>(o => o.Equals(order)),
                It.Is <CatalogueItemId>(i => i == catalogueItemId),
                It.Is <CreateOrderItemModel>(m => m == model));

            orderItemService.Setup(o => o.GetOrder(callOffId)).ReturnsAsync(order);
            createOrderItemService.Setup(createAsync).ReturnsAsync(aggregateValidationResult);

            var response = await controller.CreateOrderItemAsync(callOffId, catalogueItemId, model);

            response.Should().BeOfType <BadRequestObjectResult>();
            response.As <BadRequestObjectResult>().Value.Should().BeOfType <ValidationProblemDetails>();
        }
コード例 #3
0
        public static async Task CreateOrderItemAsync_OrderExists_ReturnsCreatedAtActionResult(
            [Frozen] Mock <ICreateOrderItemService> createOrderItemService,
            [Frozen] Mock <IOrderItemService> orderItemService,
            [Frozen] CallOffId callOffId,
            CatalogueItemId catalogueItemId,
            Order order,
            CreateOrderItemModel model,
            OrderItemsController controller)
        {
            Expression <Func <ICreateOrderItemService, Task <AggregateValidationResult> > > createAsync = s => s.CreateAsync(
                It.Is <Order>(o => o.Equals(order)),
                It.Is <CatalogueItemId>(i => i == catalogueItemId),
                It.Is <CreateOrderItemModel>(m => m == model));

            orderItemService.Setup(o => o.GetOrder(callOffId)).ReturnsAsync(order);
            createOrderItemService.Setup(createAsync).ReturnsAsync(new AggregateValidationResult());

            var result = await controller.CreateOrderItemAsync(callOffId, catalogueItemId, model);

            result.Should().BeOfType <CreatedAtActionResult>();
            result.As <CreatedAtActionResult>().Should().BeEquivalentTo(new
            {
                ActionName  = "Get",
                RouteValues = new RouteValueDictionary
                {
                    { nameof(callOffId), callOffId.ToString() },
                    { nameof(catalogueItemId), catalogueItemId.ToString() },
                },
            });
        }
コード例 #4
0
        public async Task <IActionResult> CreateOrderItemAsync(
            CallOffId callOffId,
            CatalogueItemId catalogueItemId,
            CreateOrderItemModel model)
        {
            if (model is null)
            {
                throw new ArgumentNullException(nameof(model));
            }

            var order = await orderItemService.GetOrder(callOffId);

            if (order is null)
            {
                return(NotFound());
            }

            var validationResult = await createOrderItemService.CreateAsync(order, catalogueItemId, model);

            if (validationResult.Success)
            {
                return(CreatedAtAction(
                           nameof(GetAsync).TrimAsync(),
                           new { callOffId = callOffId.ToString(), catalogueItemId = catalogueItemId.ToString() },
                           null));
            }

            foreach ((string key, string errorMessage) in validationResult.ToModelErrors())
            {
                ModelState.AddModelError(key, errorMessage);
            }

            return(ValidationProblem(ModelState));
        }
        public async Task <ActionResult <CreateOrderItemResponseModel> > CreateOrderItemAsync(
            string orderId,
            CreateOrderItemModel model)
        {
            var order = await _orderRepository.GetOrderByIdAsync(orderId);

            if (order is null)
            {
                return(NotFound());
            }

            var primaryOrganisationId = User.GetPrimaryOrganisationId();

            if (primaryOrganisationId != order.OrganisationId)
            {
                return(Forbid());
            }

            var createOrderItemResponse = new CreateOrderItemResponseModel();

            var result = await _createOrderItemService.CreateAsync(model.ToRequest(order, CatalogueItemType.Solution));

            if (result.IsSuccess)
            {
                createOrderItemResponse.OrderItemId = result.Value;
                return(CreatedAtAction(nameof(GetOrderItemAsync).TrimAsync(), null, new { orderId, orderItemId = createOrderItemResponse.OrderItemId }, createOrderItemResponse));
            }

            createOrderItemResponse.Errors = result.Errors.Select(x => new ErrorModel(x.Id, x.Field));
            return(BadRequest(createOrderItemResponse));
        }
コード例 #6
0
        public static CreateOrderItemRequest ToRequest(
            this CreateOrderItemModel model,
            Order order,
            CatalogueItemType catalogueItemType)
        {
            if (model is null)
            {
                throw new ArgumentNullException(nameof(model));
            }

            if (order is null)
            {
                throw new ArgumentNullException(nameof(order));
            }

            return(new CreateOrderItemRequest(
                       order,
                       model.ServiceRecipient?.OdsCode,
                       model.CatalogueSolutionId,
                       catalogueItemType,
                       model.CatalogueSolutionName,
                       model.ProvisioningType,
                       model.Type,
                       model.ItemUnitModel?.Name,
                       model.ItemUnitModel?.Description,
                       null,
                       model.CurrencyCode,
                       model.Quantity,
                       model.EstimationPeriod,
                       model.DeliveryDate,
                       model.Price));
        }
コード例 #7
0
        public static void Validate_DeliveryDateAfterMaxDeliveryDateOffsetInDays_SuccessIsFalse(
            Order order,
            CreateOrderItemModel model,
            CatalogueItemType itemType,
            ValidationSettings validationSettings)
        {
            model.ServiceRecipients.Should().NotBeNullOrEmpty();

            OrderItemValidator orderItemValidator = new OrderItemValidator(validationSettings);

            var serviceRecipients = model.ServiceRecipients.Select(_ =>
                                                                   new OrderItemRecipientModel {
                DeliveryDate = order.CommencementDate.Value.AddDays(validationSettings.MaxDeliveryDateOffsetInDays + 1)
            }).ToList();

            var result = orderItemValidator.Validate(order, new CreateOrderItemModel {
                ServiceRecipients = serviceRecipients
            }, itemType);

            result.FailedValidations.Should().NotBeEmpty();

            foreach ((_, ValidationResult validationResult) in result.FailedValidations)
            {
                var errorDetails = validationResult.Errors.SingleOrDefault();
                errorDetails.Should().NotBeNull();
                errorDetails.Field.Should().Be("DeliveryDate");
                errorDetails.Id.Should().Be("DeliveryDateOutsideDeliveryWindow");
            }

            result.Success.Should().BeFalse();
        }
        public static async Task CreateAsync_RemovesDefaultDeliveryDate(
            [Frozen] ApplicationDbContext context,
            [Frozen] Mock <ICreateOrderItemValidator> orderItemValidator,
            [Frozen] Mock <IServiceRecipientService> serviceRecipientService,
            Order order,
            CatalogueItemId catalogueItemId,
            CreateOrderItemModel model,
            CreateOrderItemService service)
        {
            order.SetDefaultDeliveryDate(catalogueItemId, DateTime.Now.AddDays(10));
            context.Order.Add(order);
            await context.SaveChangesAsync();

            order.DefaultDeliveryDates.Should().NotBeEmpty();

            var aggregateValidationResult = new AggregateValidationResult();

            aggregateValidationResult.AddValidationResult(new ValidationResult(), 0);

            var catalogueItemType = Enum.Parse <CatalogueItemType>(model.CatalogueItemType, true);

            var serviceRecipients = model.ServiceRecipients.Select(r => new ServiceRecipient(r.OdsCode, r.Name));

            orderItemValidator.Setup(o => o.Validate(order, model, catalogueItemType)).Returns(aggregateValidationResult);
            serviceRecipientService.Setup(r => r.AddOrUpdateServiceRecipients(It.IsAny <IEnumerable <ServiceRecipient> >()))
            .ReturnsAsync(serviceRecipients.ToDictionary(r => r.OdsCode));

            await service.CreateAsync(order, catalogueItemId, model);

            var defaultDeliveryDateResult = context.Set <DefaultDeliveryDate>().FirstOrDefault(d => d.OrderId.Equals(order.Id));

            defaultDeliveryDateResult.Should().BeNull();
        }
        public static async Task CreateAsync_CatalogueItemSavedToDb(
            [Frozen] ApplicationDbContext context,
            [Frozen] Mock <ICreateOrderItemValidator> orderItemValidator,
            [Frozen] Mock <IServiceRecipientService> serviceRecipientService,
            Order order,
            CatalogueItemId catalogueItemId,
            CreateOrderItemModel model,
            CreateOrderItemService service)
        {
            context.Order.Add(order);
            await context.SaveChangesAsync();

            var aggregateValidationResult = new AggregateValidationResult();

            aggregateValidationResult.AddValidationResult(new ValidationResult(), 0);

            var catalogueItemType = Enum.Parse <CatalogueItemType>(model.CatalogueItemType, true);

            var serviceRecipients = model.ServiceRecipients.Select(r => new ServiceRecipient(r.OdsCode, r.Name));

            orderItemValidator.Setup(o => o.Validate(order, model, catalogueItemType)).Returns(aggregateValidationResult);
            serviceRecipientService.Setup(r => r.AddOrUpdateServiceRecipients(It.IsAny <IEnumerable <ServiceRecipient> >()))
            .ReturnsAsync(serviceRecipients.ToDictionary(r => r.OdsCode));

            await service.CreateAsync(order, catalogueItemId, model);

            var expectedOrderItem = context.Set <OrderItem>().First(o => o.CatalogueItem.Id.Equals(catalogueItemId));

            expectedOrderItem.CatalogueItem.Name.Should().Be(model.CatalogueItemName);
        }
コード例 #10
0
        public static void Validate_NullDeliveryDate_SuccessIsFalse(
            Order order,
            CreateOrderItemModel model,
            OrderItemValidator orderItemValidator)
        {
            model.ServiceRecipients.Should().NotBeNullOrEmpty();
            order.CommencementDate.Should().NotBeNull();

            var serviceRecipients = model.ServiceRecipients.Select(_ =>
                                                                   new OrderItemRecipientModel {
                DeliveryDate = null
            }).ToList();

            var result = orderItemValidator.Validate(order, new CreateOrderItemModel {
                ServiceRecipients = serviceRecipients
            }, CatalogueItemType.AdditionalService);

            result.FailedValidations.Should().NotBeEmpty();

            foreach ((_, ValidationResult validationResult) in result.FailedValidations)
            {
                var errorDetails = validationResult.Errors.SingleOrDefault();
                errorDetails.Should().NotBeNull();
                errorDetails.Field.Should().Be("DeliveryDate");
                errorDetails.Id.Should().Be("DeliveryDateRequired");
            }

            result.Success.Should().BeFalse();
        }
コード例 #11
0
        public static void Validate_DeliveryDateWithinMaxDeliveryDateOffsetInDays_SuccessIsTrue(
            Order order,
            CreateOrderItemModel model,
            CatalogueItemType itemType,
            ValidationSettings validationSettings)
        {
            model.ServiceRecipients.Should().NotBeNullOrEmpty();

            itemType.Should().NotBe(CatalogueItemType.AssociatedService);

            var serviceRecipients = model.ServiceRecipients.Select(_ =>
                                                                   new OrderItemRecipientModel {
                DeliveryDate = order.CommencementDate.Value.AddDays(validationSettings.MaxDeliveryDateOffsetInDays - 1)
            }).ToList();

            OrderItemValidator orderItemValidator = new OrderItemValidator(validationSettings);

            order.CommencementDate.Should().NotBeNull();

            var result = orderItemValidator.Validate(order, new CreateOrderItemModel {
                ServiceRecipients = serviceRecipients
            }, itemType);

            result.FailedValidations.Should().BeEmpty();
            result.Success.Should().BeTrue();
        }
コード例 #12
0
        public static void Validate_PriceIdIsNotNull_DoesNotHaveError(
            CreateOrderItemModel model,
            CreateOrderItemModelValidator validator)
        {
            var result = validator.TestValidate(model);

            result.ShouldNotHaveValidationErrorFor(m => m.PriceId);
        }
コード例 #13
0
        public static async Task CreateOrderItemAsync_OrderDoesNotExist_ReturnsNotFound(
            CallOffId callOffId,
            CatalogueItemId catalogueItemId,
            CreateOrderItemModel model,
            OrderItemsController controller)
        {
            var result = await controller.CreateOrderItemAsync(callOffId, catalogueItemId, model);

            result.Should().BeOfType <NotFoundResult>();
        }
コード例 #14
0
        public static void Validate_NullCommencementDate_ThrowsArgumentNullException(
            Order order,
            CreateOrderItemModel model,
            CatalogueItemType itemType,
            OrderItemValidator orderItemValidator)
        {
            order.CommencementDate = null;

            Assert.Throws <ArgumentNullException>(() => _ = orderItemValidator.Validate(order, model, itemType));
        }
コード例 #15
0
        public static void Validate_PriceIsValid_DoesNotHaveError(decimal price)
        {
            var model = new CreateOrderItemModel {
                Price = price
            };
            var validator = new CreateOrderItemModelValidator();

            var result = validator.TestValidate(model);

            result.ShouldNotHaveValidationErrorFor(m => m.Price);
        }
コード例 #16
0
        public static void Validate_ProvisioningTypeIsValid_DoesNotHaveError(
            string provisioningType,
            CreateOrderItemModel model,
            CreateOrderItemModelValidator validator)
        {
            model.ProvisioningType = provisioningType;

            var result = validator.TestValidate(model);

            result.ShouldNotHaveValidationErrorFor(m => m.ProvisioningType);
        }
コード例 #17
0
        public static void Validate_CatalogueItemNameIsValid_DoesNotHaveError(
            CreateOrderItemModelValidator validator)
        {
            var model = new CreateOrderItemModel {
                CatalogueItemName = new string('A', 255)
            };

            var result = validator.TestValidate(model);

            result.ShouldNotHaveValidationErrorFor(m => m.CatalogueItemName);
        }
コード例 #18
0
        public static void Validate_CatalogueSolutionIdIsValid_IsAdditionalService_DoesNotHaveError(
            CreateOrderItemModel model,
            CreateOrderItemModelValidator validator)
        {
            model.CatalogueItemType   = nameof(CatalogueItemType.AdditionalService);
            model.CatalogueSolutionId = new CatalogueItemId(1, "001").ToString();

            var result = validator.TestValidate(model);

            result.ShouldNotHaveValidationErrorFor(m => m.CatalogueSolutionId);
        }
コード例 #19
0
        public static void Validate_CurrencyCodeIsValid_DoesNotHaveError(
            CreateOrderItemModelValidator validator)
        {
            var model = new CreateOrderItemModel {
                CurrencyCode = "GBP"
            };

            var result = validator.TestValidate(model);

            result.ShouldNotHaveValidationErrorFor(m => m.CurrencyCode);
        }
コード例 #20
0
        public static void Validate_PriceIsNull_HasError(
            CreateOrderItemModelValidator validator)
        {
            var model = new CreateOrderItemModel();

            var result = validator.TestValidate(model);

            result
            .ShouldHaveValidationErrorFor(m => m.Price)
            .WithErrorMessage($"{nameof(CreateOrderItemModel.Price)}Required");
        }
コード例 #21
0
        private async Task <PricingUnit> AddOrUpdatePricingUnit(CreateOrderItemModel model)
        {
            var pricingUnit = await context.FindAsync <PricingUnit>(model.ItemUnit.Name) ?? new PricingUnit
            {
                Name = model.ItemUnit.Name,
            };

            pricingUnit.Description = model.ItemUnit.Description;

            return(pricingUnit);
        }
コード例 #22
0
        public static void Validate_TimeUnitIsNull_IsOnDemand_DoesNotHaveError(
            CreateOrderItemModel model,
            CreateOrderItemModelValidator validator)
        {
            model.ProvisioningType = nameof(ProvisioningType.OnDemand);
            model.TimeUnit         = null;

            var result = validator.TestValidate(model);

            result.ShouldNotHaveValidationErrorFor(m => m.TimeUnit);
        }
コード例 #23
0
        public static void Validate_CatalogueItemTypeIsValid_DoesNotHaveError(
            string catalogueItemType,
            CreateOrderItemModel model,
            CreateOrderItemModelValidator validator)
        {
            model.CatalogueItemType = catalogueItemType;

            var result = validator.TestValidate(model);

            result.ShouldNotHaveValidationErrorFor(m => m.CatalogueItemType);
        }
コード例 #24
0
        public static void Validate_CatalogueItemTypeIsEmpty_HasError(
            string catalogueItemType,
            CreateOrderItemModel model,
            CreateOrderItemModelValidator validator)
        {
            model.CatalogueItemType = catalogueItemType;
            var result = validator.TestValidate(model);

            result
            .ShouldHaveValidationErrorFor(m => m.CatalogueItemType)
            .WithErrorMessage($"{nameof(CreateOrderItemModel.CatalogueItemType)}Required");
        }
コード例 #25
0
        public static void Validate_EstimationPeriodIsNotValid_IsNotOnDemand_DoesNotHaveError(
            string provisioningType,
            CreateOrderItemModel model,
            CreateOrderItemModelValidator validator)
        {
            model.ProvisioningType = provisioningType;
            model.EstimationPeriod = "InvalidTimeUnit";

            var result = validator.TestValidate(model);

            result.ShouldNotHaveValidationErrorFor(m => m.EstimationPeriod);
        }
コード例 #26
0
        public static void Validate_EstimationPeriodIsValid_IsOnDemand_DoesNotHaveError(
            string estimationPeriod,
            CreateOrderItemModel model,
            CreateOrderItemModelValidator validator)
        {
            model.ProvisioningType = nameof(ProvisioningType.OnDemand);
            model.EstimationPeriod = estimationPeriod;

            var result = validator.TestValidate(model);

            result.ShouldNotHaveValidationErrorFor(m => m.EstimationPeriod);
        }
コード例 #27
0
        public static void Validate_CatalogueItemTypeIsNotValid_HasError(
            CreateOrderItemModel model,
            CreateOrderItemModelValidator validator)
        {
            model.CatalogueItemType = "InvalidCatalogueItemType";

            var result = validator.TestValidate(model);

            result
            .ShouldHaveValidationErrorFor(m => m.CatalogueItemType)
            .WithErrorMessage($"{nameof(CreateOrderItemModel.CatalogueItemType)}ValidValue");
        }
コード例 #28
0
        public static void Validate_CatalogueSolutionIdIsNull_IsNotAdditionalService_DoesNotHaveError(
            string catalogueItemType,
            CreateOrderItemModel model,
            CreateOrderItemModelValidator validator)
        {
            model.CatalogueItemType   = catalogueItemType;
            model.CatalogueSolutionId = null;

            var result = validator.TestValidate(model);

            result.ShouldNotHaveValidationErrorFor(m => m.CatalogueSolutionId);
        }
コード例 #29
0
        public static void Validate_TypeIsValid_DoesNotHaveError(
            string type,
            CreateOrderItemModelValidator validator)
        {
            var model = new CreateOrderItemModel {
                Type = type
            };

            var result = validator.TestValidate(model);

            result.ShouldNotHaveValidationErrorFor(m => m.Type);
        }
コード例 #30
0
        public static void Validate_ItemUnitIsNotNull_DoesNotHaveError(
            ItemUnitModel itemUnit,
            CreateOrderItemModelValidator validator)
        {
            var model = new CreateOrderItemModel {
                ItemUnit = itemUnit
            };

            var result = validator.TestValidate(model);

            result.ShouldNotHaveValidationErrorFor(m => m.ItemUnit);
        }