@@ -623,4 +623,89 @@ private class TestStore(IDictionary<string, byte[]> state) : IPersistentComponen
623623 public Task < IDictionary < string , byte [ ] > > GetPersistedStateAsync ( ) => Task . FromResult ( state ) ;
624624 public Task PersistStateAsync ( IReadOnlyDictionary < string , byte [ ] > state ) => throw new NotImplementedException ( ) ;
625625 }
626+
627+ private class ComponentWithPrivateProperty : IComponent
628+ {
629+ [ PersistentState ]
630+ private string PrivateValue { get ; set ; } = "initial" ;
631+
632+ public void Attach ( RenderHandle renderHandle ) => throw new NotImplementedException ( ) ;
633+ public Task SetParametersAsync ( ParameterView parameters ) => throw new NotImplementedException ( ) ;
634+ }
635+
636+ private class ComponentWithPrivateGetter : IComponent
637+ {
638+ [ PersistentState ]
639+ public string PropertyWithPrivateGetter { private get ; set ; } = "initial" ;
640+
641+ public void Attach ( RenderHandle renderHandle ) => throw new NotImplementedException ( ) ;
642+ public Task SetParametersAsync ( ParameterView parameters ) => throw new NotImplementedException ( ) ;
643+ }
644+
645+ [ Fact ]
646+ public void Constructor_ThrowsClearException_ForPrivateProperty ( )
647+ {
648+ // Arrange
649+ var state = new PersistentComponentState ( new Dictionary < string , byte [ ] > ( ) , [ ] , [ ] ) ;
650+ state . InitializeExistingState ( new Dictionary < string , byte [ ] > ( ) , RestoreContext . InitialValue ) ;
651+ var renderer = new TestRenderer ( ) ;
652+ var component = new ComponentWithPrivateProperty ( ) ;
653+ var componentState = CreateComponentState ( renderer , component , null , null ) ;
654+ var cascadingParameterInfo = CreateCascadingParameterInfo ( "PrivateValue" , typeof ( string ) ) ;
655+ var serviceProvider = new ServiceCollection ( ) . BuildServiceProvider ( ) ;
656+ var logger = NullLogger . Instance ;
657+
658+ // Act & Assert
659+ var exception = Assert . Throws < InvalidOperationException > ( ( ) =>
660+ new PersistentValueProviderComponentSubscription (
661+ state , componentState , cascadingParameterInfo , serviceProvider , logger ) ) ;
662+
663+ // Should throw a clear error about needing a public property with public getter
664+ Assert . Contains ( "A public property" , exception . Message ) ;
665+ Assert . Contains ( "with a public getter wasn't found" , exception . Message ) ;
666+ }
667+
668+ [ Fact ]
669+ public void Constructor_ThrowsClearException_ForPrivateGetter ( )
670+ {
671+ // Arrange
672+ var state = new PersistentComponentState ( new Dictionary < string , byte [ ] > ( ) , [ ] , [ ] ) ;
673+ state . InitializeExistingState ( new Dictionary < string , byte [ ] > ( ) , RestoreContext . InitialValue ) ;
674+ var renderer = new TestRenderer ( ) ;
675+ var component = new ComponentWithPrivateGetter ( ) ;
676+ var componentState = CreateComponentState ( renderer , component , null , null ) ;
677+ var cascadingParameterInfo = CreateCascadingParameterInfo ( nameof ( ComponentWithPrivateGetter . PropertyWithPrivateGetter ) , typeof ( string ) ) ;
678+ var serviceProvider = new ServiceCollection ( ) . BuildServiceProvider ( ) ;
679+ var logger = NullLogger . Instance ;
680+
681+ // Act & Assert
682+ var exception = Assert . Throws < InvalidOperationException > ( ( ) =>
683+ new PersistentValueProviderComponentSubscription (
684+ state , componentState , cascadingParameterInfo , serviceProvider , logger ) ) ;
685+
686+ // Should throw a clear error about needing a public property with public getter
687+ Assert . Contains ( "A public property" , exception . Message ) ;
688+ Assert . Contains ( "with a public getter wasn't found" , exception . Message ) ;
689+ }
690+
691+ [ Fact ]
692+ public void Constructor_WorksCorrectly_ForPublicProperty ( )
693+ {
694+ // Arrange
695+ var state = new PersistentComponentState ( new Dictionary < string , byte [ ] > ( ) , [ ] , [ ] ) ;
696+ state . InitializeExistingState ( new Dictionary < string , byte [ ] > ( ) , RestoreContext . InitialValue ) ;
697+ var renderer = new TestRenderer ( ) ;
698+ var component = new TestComponent { State = "test-value" } ;
699+ var componentState = CreateComponentState ( renderer , component , null , null ) ;
700+ var cascadingParameterInfo = CreateCascadingParameterInfo ( nameof ( TestComponent . State ) , typeof ( string ) ) ;
701+ var serviceProvider = new ServiceCollection ( ) . BuildServiceProvider ( ) ;
702+ var logger = NullLogger . Instance ;
703+
704+ // Act & Assert - Should not throw
705+ var subscription = new PersistentValueProviderComponentSubscription (
706+ state , componentState , cascadingParameterInfo , serviceProvider , logger ) ;
707+
708+ Assert . NotNull ( subscription ) ;
709+ subscription . Dispose ( ) ;
710+ }
626711}
0 commit comments