@@ -362,6 +362,7 @@ public async Task RespondsToValidationStateChangeNotifications()
362
362
var inputComponentId = componentFrame1 . ComponentId ;
363
363
var component = ( TestInputComponent < string > ) componentFrame1 . Component ;
364
364
Assert . Equal ( "valid" , component . CssClass ) ;
365
+ Assert . Null ( component . AdditionalAttributes ) ;
365
366
366
367
// Act: update the field state in the EditContext and notify
367
368
var messageStore = new ValidationMessageStore ( rootComponent . EditContext ) ;
@@ -372,6 +373,8 @@ public async Task RespondsToValidationStateChangeNotifications()
372
373
var batch2 = renderer . Batches . Skip ( 1 ) . Single ( ) ;
373
374
Assert . Equal ( inputComponentId , batch2 . DiffsByComponentId . Keys . Single ( ) ) ;
374
375
Assert . Equal ( "invalid" , component . CssClass ) ;
376
+ Assert . NotNull ( component . AdditionalAttributes ) ;
377
+ Assert . True ( component . AdditionalAttributes . ContainsKey ( "aria-invalid" ) ) ;
375
378
}
376
379
377
380
[ Fact ]
@@ -400,6 +403,73 @@ public async Task UnsubscribesFromValidationStateChangeNotifications()
400
403
Assert . Empty ( renderer . Batches . Skip ( 1 ) ) ;
401
404
}
402
405
406
+ [ Fact ]
407
+ public async Task AriaAttributeIsRenderedWhenTheValidationStateIsInvalidOnFirstRender ( )
408
+ {
409
+ // Arrange// Arrange
410
+ var model = new TestModel ( ) ;
411
+ var invalidContext = new EditContext ( model ) ;
412
+
413
+ var rootComponent = new TestInputHostComponent < string , TestInputComponent < string > >
414
+ {
415
+ EditContext = invalidContext ,
416
+ ValueExpression = ( ) => model . StringProperty
417
+ } ;
418
+
419
+ var fieldIdentifier = FieldIdentifier . Create ( ( ) => model . StringProperty ) ;
420
+ var messageStore = new ValidationMessageStore ( invalidContext ) ;
421
+ messageStore . Add ( fieldIdentifier , "Test error message" ) ;
422
+
423
+ var renderer = new TestRenderer ( ) ;
424
+ var rootComponentId = renderer . AssignRootComponentId ( rootComponent ) ;
425
+ await renderer . RenderRootComponentAsync ( rootComponentId ) ;
426
+
427
+
428
+ // Initally, it rendered one batch and is valid
429
+ var batch1 = renderer . Batches . Single ( ) ;
430
+ var componentFrame1 = batch1 . GetComponentFrames < TestInputComponent < string > > ( ) . Single ( ) ;
431
+ var inputComponentId = componentFrame1 . ComponentId ;
432
+ var component = ( TestInputComponent < string > ) componentFrame1 . Component ;
433
+ Assert . Equal ( "invalid" , component . CssClass ) ;
434
+ Assert . NotNull ( component . AdditionalAttributes ) ;
435
+ Assert . Equal ( 1 , component . AdditionalAttributes . Count ) ;
436
+ Assert . True ( ( bool ) component . AdditionalAttributes [ "aria-invalid" ] ) ;
437
+ }
438
+
439
+ [ Fact ]
440
+ public async Task UserSpecifiedAriaValueIsNotChangedIfInvalid ( )
441
+ {
442
+ // Arrange// Arrange
443
+ var model = new TestModel ( ) ;
444
+ var invalidContext = new EditContext ( model ) ;
445
+
446
+ var rootComponent = new TestInputHostComponent < string , TestInputComponent < string > >
447
+ {
448
+ EditContext = invalidContext ,
449
+ ValueExpression = ( ) => model . StringProperty
450
+ } ;
451
+ rootComponent . AdditionalAttributes = new Dictionary < string , object > ( ) ;
452
+ rootComponent . AdditionalAttributes [ "aria-invalid" ] = "userSpecifiedValue" ;
453
+
454
+ var fieldIdentifier = FieldIdentifier . Create ( ( ) => model . StringProperty ) ;
455
+ var messageStore = new ValidationMessageStore ( invalidContext ) ;
456
+ messageStore . Add ( fieldIdentifier , "Test error message" ) ;
457
+
458
+ var renderer = new TestRenderer ( ) ;
459
+ var rootComponentId = renderer . AssignRootComponentId ( rootComponent ) ;
460
+ await renderer . RenderRootComponentAsync ( rootComponentId ) ;
461
+
462
+ // Initally, it rendered one batch and is valid
463
+ var batch1 = renderer . Batches . Single ( ) ;
464
+ var componentFrame1 = batch1 . GetComponentFrames < TestInputComponent < string > > ( ) . Single ( ) ;
465
+ var inputComponentId = componentFrame1 . ComponentId ;
466
+ var component = ( TestInputComponent < string > ) componentFrame1 . Component ;
467
+ Assert . Equal ( "invalid" , component . CssClass ) ;
468
+ Assert . NotNull ( component . AdditionalAttributes ) ;
469
+ Assert . Equal ( 1 , component . AdditionalAttributes . Count ) ;
470
+ Assert . Equal ( "userSpecifiedValue" , component . AdditionalAttributes [ "aria-invalid" ] ) ;
471
+ }
472
+
403
473
private static TComponent FindComponent < TComponent > ( CapturedBatch batch )
404
474
=> batch . ReferenceFrames
405
475
. Where ( f => f . FrameType == RenderTreeFrameType . Component )
0 commit comments