public async Task CanCreateModel_ReturnsTrue_IfNotIsTopLevelObject_BasedOnValueAvailability(
            bool valueAvailable)
        {
            // Arrange
            var mockValueProvider = new Mock<IValueProvider>(MockBehavior.Strict);
            mockValueProvider
                .Setup(provider => provider.ContainsPrefixAsync("SimpleContainer.Simple.Name"))
                .Returns(Task.FromResult(valueAvailable));

            var typeMetadata = GetMetadataForType(typeof(SimpleContainer));
            var modelMetadata = typeMetadata.Properties[nameof(SimpleContainer.Simple)];
            var bindingContext = new MutableObjectBinderContext
            {
                ModelBindingContext = new ModelBindingContext
                {
                    ModelMetadata = modelMetadata,
                    ModelName = "SimpleContainer.Simple",
                    OperationBindingContext = new OperationBindingContext
                    {
                        ValidatorProvider = Mock.Of<IModelValidatorProvider>(),
                        ValueProvider = mockValueProvider.Object,
                        MetadataProvider = TestModelMetadataProvider.CreateDefaultProvider(),
                    },
                    ValueProvider = mockValueProvider.Object,
                },
                PropertyMetadata = modelMetadata.Properties,
            };

            var mutableBinder = new MutableObjectModelBinder();

            // Act
            var result = await mutableBinder.CanCreateModel(bindingContext);

            // Assert
            // Result matches whether first Simple property can bind.
            Assert.Equal(valueAvailable, result);
        }
        public async Task CanCreateModel_ReturnsFalse_IfNotIsTopLevelObjectAndModelIsMarkedWithBinderMetadata()
        {
            // Get the property metadata so that it is not a top level object.
            var modelMetadata = GetMetadataForType(typeof(Document))
                .Properties
                .First(metadata => metadata.PropertyName == nameof(Document.SubDocument));
            var bindingContext = new MutableObjectBinderContext
            {
                ModelBindingContext = new ModelBindingContext
                {
                    ModelMetadata = modelMetadata,
                    OperationBindingContext = new OperationBindingContext
                    {
                        ValidatorProvider = Mock.Of<IModelValidatorProvider>(),
                    },
                    BindingSource = modelMetadata.BindingSource,
                    BinderModelName = modelMetadata.BinderModelName,
                }
            };

            var mutableBinder = new MutableObjectModelBinder();

            // Act
            var canCreate = await mutableBinder.CanCreateModel(bindingContext);

            // Assert
            Assert.False(canCreate);
        }
        public async Task CanCreateModel_ReturnsTrue_IfIsTopLevelObjectAndModelIsMarkedWithBinderMetadata()
        {
            var bindingContext = new MutableObjectBinderContext
            {
                ModelBindingContext = new ModelBindingContext
                {
                    // Here the metadata represents a top level object.
                    IsTopLevelObject = true,

                    ModelMetadata = GetMetadataForType(typeof(Document)),
                    OperationBindingContext = new OperationBindingContext
                    {
                        ValidatorProvider = Mock.Of<IModelValidatorProvider>(),
                    }
                }
            };

            var mutableBinder = new MutableObjectModelBinder();

            // Act
            var canCreate = await mutableBinder.CanCreateModel(bindingContext);

            // Assert
            Assert.True(canCreate);
        }