コード例 #1
0
ファイル: InputNumberTest.cs プロジェクト: wserr/AspNetCore
        public async Task ValidationErrorUsesDisplayAttributeName()
        {
            // Arrange
            var model         = new TestModel();
            var rootComponent = new TestInputHostComponent <int, TestInputNumberComponent>
            {
                EditContext          = new EditContext(model),
                ValueExpression      = () => model.SomeNumber,
                AdditionalAttributes = new Dictionary <string, object>
                {
                    { "DisplayName", "Some number" }
                }
            };
            var fieldIdentifier = FieldIdentifier.Create(() => model.SomeNumber);
            var inputComponent  = await InputRenderer.RenderAndGetComponent(rootComponent);

            // Act
            await inputComponent.SetCurrentValueAsStringAsync("notANumber");

            // Assert
            var validationMessages = rootComponent.EditContext.GetValidationMessages(fieldIdentifier);

            Assert.NotEmpty(validationMessages);
            Assert.Contains("The Some number field must be a number.", validationMessages);
        }
コード例 #2
0
        public async Task RespondsToValidationStateChangeNotifications()
        {
            // Arrange
            var model         = new TestModel();
            var rootComponent = new TestInputHostComponent <string, TestInputComponent <string> >
            {
                EditContext     = new EditContext(model),
                ValueExpression = () => model.StringProperty
            };
            var fieldIdentifier = FieldIdentifier.Create(() => model.StringProperty);
            var renderer        = new TestRenderer();
            var rootComponentId = renderer.AssignRootComponentId(rootComponent);
            await renderer.RenderRootComponentAsync(rootComponentId);

            // Initally, it rendered one batch and is valid
            var batch1           = renderer.Batches.Single();
            var componentFrame1  = batch1.GetComponentFrames <TestInputComponent <string> >().Single();
            var inputComponentId = componentFrame1.ComponentId;
            var component        = (TestInputComponent <string>)componentFrame1.Component;

            Assert.Equal("valid", component.CssClass);

            // Act: update the field state in the EditContext and notify
            var messageStore = new ValidationMessageStore(rootComponent.EditContext);

            messageStore.Add(fieldIdentifier, "Some message");
            await renderer.Dispatcher.InvokeAsync(rootComponent.EditContext.NotifyValidationStateChanged);

            // Assert: The input component rendered itself again and now has the new class
            var batch2 = renderer.Batches.Skip(1).Single();

            Assert.Equal(inputComponentId, batch2.DiffsByComponentId.Keys.Single());
            Assert.Equal("invalid", component.CssClass);
        }
コード例 #3
0
ファイル: InputDateTest.cs プロジェクト: wserr/AspNetCore
        public async Task ValidationErrorUsesDisplayAttributeName()
        {
            // Arrange
            var model         = new TestModel();
            var rootComponent = new TestInputHostComponent <DateTime, TestInputDateComponent>
            {
                EditContext          = new EditContext(model),
                ValueExpression      = () => model.DateProperty,
                AdditionalAttributes = new Dictionary <string, object>
                {
                    { "DisplayName", "Date property" }
                }
            };
            var fieldIdentifier = FieldIdentifier.Create(() => model.DateProperty);
            var inputComponent  = await InputRenderer.RenderAndGetComponent(rootComponent);

            // Act
            await inputComponent.SetCurrentValueAsStringAsync("invalidDate");

            // Assert
            var validationMessages = rootComponent.EditContext.GetValidationMessages(fieldIdentifier);

            Assert.NotEmpty(validationMessages);
            Assert.Contains("The Date property field must be a date.", validationMessages);
        }
コード例 #4
0
        public async Task ParsesCurrentValueAsStringWhenChanged_Valid()
        {
            // Arrange
            var model            = new TestModel();
            var valueChangedArgs = new List <DateTime>();
            var rootComponent    = new TestInputHostComponent <DateTime, TestDateInputComponent>
            {
                EditContext     = new EditContext(model),
                ValueChanged    = valueChangedArgs.Add,
                ValueExpression = () => model.DateProperty
            };
            var fieldIdentifier = FieldIdentifier.Create(() => model.DateProperty);
            var inputComponent  = await RenderAndGetTestInputComponentAsync(rootComponent);

            var numValidationStateChanges = 0;

            rootComponent.EditContext.OnValidationStateChanged += (sender, eventArgs) => { numValidationStateChanges++; };

            // Act
            inputComponent.CurrentValueAsString = "1991/11/20";

            // Assert
            var receivedParsedValue = valueChangedArgs.Single();

            Assert.Equal(1991, receivedParsedValue.Year);
            Assert.Equal(11, receivedParsedValue.Month);
            Assert.Equal(20, receivedParsedValue.Day);
            Assert.True(rootComponent.EditContext.IsModified(fieldIdentifier));
            Assert.Empty(rootComponent.EditContext.GetValidationMessages(fieldIdentifier));
            Assert.Equal(0, numValidationStateChanges);
        }
コード例 #5
0
        public async Task SuppliesFieldClassCorrespondingToFieldState()
        {
            // Arrange
            var model         = new TestModel();
            var rootComponent = new TestInputHostComponent <string, TestInputComponent <string> >
            {
                EditContext     = new EditContext(model),
                ValueExpression = () => model.StringProperty
            };
            var fieldIdentifier = FieldIdentifier.Create(() => model.StringProperty);

            // Act/Assert: Initally, it's valid and unmodified
            var inputComponent = await RenderAndGetTestInputComponentAsync(rootComponent);

            Assert.Equal("valid", inputComponent.CssClass); //  no Class was specified

            // Act/Assert: Modify the field
            rootComponent.EditContext.NotifyFieldChanged(fieldIdentifier);
            Assert.Equal("modified valid", inputComponent.CssClass);

            // Act/Assert: Make it invalid
            var messages = new ValidationMessageStore(rootComponent.EditContext);

            messages.Add(fieldIdentifier, "I do not like this value");
            Assert.Equal("modified invalid", inputComponent.CssClass);

            // Act/Assert: Clear the modification flag
            rootComponent.EditContext.MarkAsUnmodified(fieldIdentifier);
            Assert.Equal("invalid", inputComponent.CssClass);

            // Act/Assert: Make it valid
            messages.Clear();
            Assert.Equal("valid", inputComponent.CssClass);
        }
コード例 #6
0
ファイル: InputBaseTest.cs プロジェクト: vchy1997/aspnetcore
        public async Task UserSpecifiedAriaValueIsNotChangedIfInvalid()
        {
            // Arrange// Arrange
            var model          = new TestModel();
            var invalidContext = new EditContext(model);

            var rootComponent = new TestInputHostComponent <string, TestInputComponent <string> >
            {
                EditContext     = invalidContext,
                ValueExpression = () => model.StringProperty
            };

            rootComponent.AdditionalAttributes = new Dictionary <string, object>();
            rootComponent.AdditionalAttributes["aria-invalid"] = "userSpecifiedValue";

            var fieldIdentifier = FieldIdentifier.Create(() => model.StringProperty);
            var messageStore    = new ValidationMessageStore(invalidContext);

            messageStore.Add(fieldIdentifier, "Test error message");

            var renderer        = new TestRenderer();
            var rootComponentId = renderer.AssignRootComponentId(rootComponent);
            await renderer.RenderRootComponentAsync(rootComponentId);

            // Initally, it rendered one batch and is valid
            var batch1           = renderer.Batches.Single();
            var componentFrame1  = batch1.GetComponentFrames <TestInputComponent <string> >().Single();
            var inputComponentId = componentFrame1.ComponentId;
            var component        = (TestInputComponent <string>)componentFrame1.Component;

            Assert.Equal("invalid", component.CssClass);
            Assert.NotNull(component.AdditionalAttributes);
            Assert.Equal(1, component.AdditionalAttributes.Count);
            Assert.Equal("userSpecifiedValue", component.AdditionalAttributes["aria-invalid"]);
        }
コード例 #7
0
ファイル: InputBaseTest.cs プロジェクト: vchy1997/aspnetcore
        public async Task UnsubscribesFromValidationStateChangeNotifications()
        {
            // Arrange
            var model         = new TestModel();
            var rootComponent = new TestInputHostComponent <string, TestInputComponent <string> >
            {
                EditContext     = new EditContext(model),
                ValueExpression = () => model.StringProperty
            };
            var fieldIdentifier = FieldIdentifier.Create(() => model.StringProperty);
            var renderer        = new TestRenderer();
            var rootComponentId = renderer.AssignRootComponentId(rootComponent);
            await renderer.RenderRootComponentAsync(rootComponentId);

            var component = renderer.Batches.Single().GetComponentFrames <TestInputComponent <string> >().Single().Component;

            // Act: dispose, then update the field state in the EditContext and notify
            ((IDisposable)component).Dispose();
            var messageStore = new ValidationMessageStore(rootComponent.EditContext);

            messageStore.Add(fieldIdentifier, "Some message");
            await renderer.Dispatcher.InvokeAsync(rootComponent.EditContext.NotifyValidationStateChanged);

            // Assert: No additional render
            Assert.Empty(renderer.Batches.Skip(1));
        }
コード例 #8
0
        public async Task CssClassCombinesClassWithFieldClass()
        {
            // Arrange
            var model         = new TestModel();
            var rootComponent = new TestInputHostComponent <string, TestInputComponent <string> >
            {
                AdditionalAttributes = new Dictionary <string, object>()
                {
                    { "class", "my-class other-class" },
                },
                EditContext     = new EditContext(model),
                ValueExpression = () => model.StringProperty
            };
            var fieldIdentifier = FieldIdentifier.Create(() => model.StringProperty);

            // Act/Assert
            var inputComponent = await RenderAndGetTestInputComponentAsync(rootComponent);

            Assert.Equal("valid", inputComponent.FieldClass);
            Assert.Equal("my-class other-class valid", inputComponent.CssClass);

            // Act/Assert: Retains custom class when changing field class
            rootComponent.EditContext.NotifyFieldChanged(fieldIdentifier);
            Assert.Equal("modified valid", inputComponent.FieldClass);
            Assert.Equal("my-class other-class modified valid", inputComponent.CssClass);
        }
コード例 #9
0
        public async Task ThrowsIfNoValueExpressionIsSupplied()
        {
            // Arrange
            var model         = new TestModel();
            var rootComponent = new TestInputHostComponent <string, TestInputComponent <string> > {
                EditContext = new EditContext(model)
            };

            // Act/Assert
            var ex = await Assert.ThrowsAsync <InvalidOperationException>(() => RenderAndGetTestInputComponentAsync(rootComponent));

            Assert.Contains($"{typeof(TestInputComponent<string>)} requires a value for the 'ValueExpression' parameter. Normally this is provided automatically when using 'bind-Value'.", ex.Message);
        }
コード例 #10
0
        public async Task ThrowsIfEditContextChanges()
        {
            // Arrange
            var model         = new TestModel();
            var rootComponent = new TestInputHostComponent <string, TestInputComponent <string> > {
                EditContext = new EditContext(model), ValueExpression = () => model.StringProperty
            };
            await InputRenderer.RenderAndGetComponent(rootComponent);

            // Act/Assert
            rootComponent.EditContext = new EditContext(model);
            var ex = Assert.Throws <InvalidOperationException>(() => rootComponent.TriggerRender());

            Assert.StartsWith($"{typeof(TestInputComponent<string>)} does not support changing the EditContext dynamically", ex.Message);
        }
コード例 #11
0
        public async Task SuppliesCurrentValueAsStringWithFormatting()
        {
            // Arrange
            var model         = new TestModel();
            var rootComponent = new TestInputHostComponent <DateTime, TestDateInputComponent>
            {
                EditContext     = new EditContext(model),
                Value           = new DateTime(1915, 3, 2),
                ValueExpression = () => model.DateProperty
            };
            var inputComponent = await RenderAndGetTestInputComponentAsync(rootComponent);

            // Act/Assert
            Assert.Equal("1915/03/02", inputComponent.CurrentValueAsString);
        }
コード例 #12
0
        public async Task ParsesCurrentValueWhenUsingNotNullableEnumWithEmptyValue()
        {
            // Arrange
            var model         = new TestModel();
            var rootComponent = new TestInputHostComponent <TestEnum, TestInputSelect <TestEnum> >
            {
                EditContext     = new EditContext(model),
                ValueExpression = () => model.NotNullableEnum
            };
            var inputSelectComponent = await InputRenderer.RenderAndGetComponent(rootComponent);

            // Act
            inputSelectComponent.CurrentValueAsString = "";

            // Assert
            Assert.Equal(default, inputSelectComponent.CurrentValue);
コード例 #13
0
        public async Task InputElementIsAssignedSuccessfully()
        {
            // Arrange
            var model         = new TestModel();
            var rootComponent = new TestInputHostComponent <string, InputTextArea>
            {
                EditContext     = new EditContext(model),
                ValueExpression = () => model.StringProperty,
            };

            // Act
            var inputSelectComponent = await InputRenderer.RenderAndGetComponent(rootComponent);

            // Assert
            Assert.NotNull(inputSelectComponent.Element);
        }
コード例 #14
0
        public async Task CanRenderWithoutEditContext()
        {
            // Arrange
            var model         = new TestModel();
            var value         = "some value";
            var rootComponent = new TestInputHostComponent <string, TestInputComponent <string> >
            {
                Value           = value,
                ValueExpression = () => value
            };

            // Act/Assert
            var inputComponent = await InputRenderer.RenderAndGetComponent(rootComponent);

            Assert.Null(inputComponent.EditContext);
        }
コード例 #15
0
        public async Task GetsCurrentValueFromValueParameter()
        {
            // Arrange
            var model         = new TestModel();
            var rootComponent = new TestInputHostComponent <string, TestInputComponent <string> >
            {
                EditContext     = new EditContext(model),
                Value           = "some value",
                ValueExpression = () => model.StringProperty
            };

            // Act
            var inputComponent = await RenderAndGetTestInputComponentAsync(rootComponent);

            // Assert
            Assert.Equal("some value", inputComponent.CurrentValue);
        }
コード例 #16
0
        public async Task ExposesEditContextToSubclass()
        {
            // Arrange
            var model         = new TestModel();
            var rootComponent = new TestInputHostComponent <string, TestInputComponent <string> >
            {
                EditContext     = new EditContext(model),
                Value           = "some value",
                ValueExpression = () => model.StringProperty
            };

            // Act
            var inputComponent = await RenderAndGetTestInputComponentAsync(rootComponent);

            // Assert
            Assert.Same(rootComponent.EditContext, inputComponent.EditContext);
        }
コード例 #17
0
        public async Task ExposesFieldIdentifierToSubclass()
        {
            // Arrange
            var model         = new TestModel();
            var rootComponent = new TestInputHostComponent <string, TestInputComponent <string> >
            {
                EditContext     = new EditContext(model),
                Value           = "some value",
                ValueExpression = () => model.StringProperty
            };

            // Act
            var inputComponent = await RenderAndGetTestInputComponentAsync(rootComponent);

            // Assert
            Assert.Equal(FieldIdentifier.Create(() => model.StringProperty), inputComponent.FieldIdentifier);
        }
コード例 #18
0
        public async Task CanReadBackChangesToCurrentValue()
        {
            // Arrange
            var model         = new TestModel();
            var rootComponent = new TestInputHostComponent <string, TestInputComponent <string> >
            {
                EditContext     = new EditContext(model),
                Value           = "initial value",
                ValueExpression = () => model.StringProperty
            };
            var inputComponent = await RenderAndGetTestInputComponentAsync(rootComponent);

            Assert.Equal("initial value", inputComponent.CurrentValue);

            // Act
            inputComponent.CurrentValue = "new value";

            // Assert
            Assert.Equal("new value", inputComponent.CurrentValue);
        }
コード例 #19
0
        public async Task WritingToCurrentValueNotifiesEditContext()
        {
            // Arrange
            var model         = new TestModel();
            var rootComponent = new TestInputHostComponent <string, TestInputComponent <string> >
            {
                EditContext     = new EditContext(model),
                Value           = "initial value",
                ValueExpression = () => model.StringProperty
            };
            var inputComponent = await RenderAndGetTestInputComponentAsync(rootComponent);

            Assert.False(rootComponent.EditContext.IsModified(() => model.StringProperty));

            // Act
            inputComponent.CurrentValue = "new value";

            // Assert
            Assert.True(rootComponent.EditContext.IsModified(() => model.StringProperty));
        }
コード例 #20
0
        public async Task WritingToCurrentValueDoesNotInvokeValueChangedIfUnchanged()
        {
            // Arrange
            var model = new TestModel();
            var valueChangedCallLog = new List <string>();
            var rootComponent       = new TestInputHostComponent <string, TestInputComponent <string> >
            {
                EditContext     = new EditContext(model),
                Value           = "initial value",
                ValueChanged    = val => valueChangedCallLog.Add(val),
                ValueExpression = () => model.StringProperty
            };
            var inputComponent = await RenderAndGetTestInputComponentAsync(rootComponent);

            Assert.Empty(valueChangedCallLog);

            // Act
            inputComponent.CurrentValue = "initial value";

            // Assert
            Assert.Empty(valueChangedCallLog);
        }
コード例 #21
0
        private static async Task <TComponent> RenderAndGetTestInputComponentAsync <TValue, TComponent>(TestInputHostComponent <TValue, TComponent> hostComponent) where TComponent : TestInputComponent <TValue>
        {
            var testRenderer = new TestRenderer();
            var componentId  = testRenderer.AssignRootComponentId(hostComponent);
            await testRenderer.RenderRootComponentAsync(componentId);

            return(FindComponent <TComponent>(testRenderer.Batches.Single()));
        }