@@ -55,48 +55,21 @@ public void Render_WithoutAuthorizeAttribute_DoesNotCallUnauthorized()
5555 }
5656
5757 [ Fact ]
58- public void Render_WithAuthorizeAttribute_WhenAnonymous_CallsUnauthorized ( )
58+ public void AuthStateCleared_WithRoleRequirement_WhenAnonymous_CallsUnauthorized_NotForbidden ( )
5959 {
6060 var state = UAuthState . Anonymous ( ) ;
6161
62- var cut =
63- RenderWithState < AuthenticationRequiredComponent > ( state ) ;
64-
65- var component = cut
66- . FindComponent < AuthenticationRequiredComponent > ( )
67- . Instance ;
68-
69- component . UnauthorizedCount . Should ( ) . Be ( 1 ) ;
70- component . ForbiddenCount . Should ( ) . Be ( 0 ) ;
71- }
72-
73- [ Fact ]
74- public void Render_WithRoleRequirement_WhenAnonymous_CallsUnauthorized_NotForbidden ( )
75- {
76- var state = UAuthState . Anonymous ( ) ;
77-
78- var cut =
79- RenderWithState < AdminRequiredComponent > ( state ) ;
62+ var cut = RenderWithState < AdminRequiredComponent > ( state ) ;
8063
8164 var component = cut
8265 . FindComponent < AdminRequiredComponent > ( )
8366 . Instance ;
8467
85- component . UnauthorizedCount . Should ( ) . Be ( 1 ) ;
68+ // Initial render must not make a premature authorization decision.
69+ component . UnauthorizedCount . Should ( ) . Be ( 0 ) ;
8670 component . ForbiddenCount . Should ( ) . Be ( 0 ) ;
87- }
8871
89- [ Fact ]
90- public void Render_WithPermissionRequirement_WhenAnonymous_CallsUnauthorized_NotForbidden ( )
91- {
92- var state = UAuthState . Anonymous ( ) ;
93-
94- var cut =
95- RenderWithState < ReadUsersRequiredComponent > ( state ) ;
96-
97- var component = cut
98- . FindComponent < ReadUsersRequiredComponent > ( )
99- . Instance ;
72+ state . Clear ( ) ;
10073
10174 component . UnauthorizedCount . Should ( ) . Be ( 1 ) ;
10275 component . ForbiddenCount . Should ( ) . Be ( 0 ) ;
@@ -146,17 +119,22 @@ public void Render_WithRequiredRole_WhenUserHasRole_DoesNotReject()
146119 }
147120
148121 [ Fact ]
149- public void Render_WithRequiredRole_WhenUserDoesNotHaveRole_CallsForbidden ( )
122+ public void AuthStateChanged_WithRequiredRole_WhenUserDoesNotHaveRole_CallsForbidden ( )
150123 {
151124 var state = AuthenticatedState (
152- roles : [ "member " ] ) ;
125+ roles : [ "User " ] ) ;
153126
154127 var cut = RenderWithState < AdminRequiredComponent > ( state ) ;
155128
156129 var component = cut
157130 . FindComponent < AdminRequiredComponent > ( )
158131 . Instance ;
159132
133+ component . UnauthorizedCount . Should ( ) . Be ( 0 ) ;
134+ component . ForbiddenCount . Should ( ) . Be ( 0 ) ;
135+
136+ state . MarkStale ( ) ;
137+
160138 component . UnauthorizedCount . Should ( ) . Be ( 0 ) ;
161139 component . ForbiddenCount . Should ( ) . Be ( 1 ) ;
162140 }
@@ -178,7 +156,7 @@ public void Render_WithRequiredPermission_WhenUserHasPermission_DoesNotReject()
178156 }
179157
180158 [ Fact ]
181- public void Render_WithRequiredPermission_WhenUserDoesNotHavePermission_CallsForbidden ( )
159+ public void AuthStateChanged_WithRequiredPermission_WhenUserDoesNotHavePermission_CallsForbidden ( )
182160 {
183161 var state = AuthenticatedState (
184162 permissions : [ "users.list" ] ) ;
@@ -189,6 +167,12 @@ public void Render_WithRequiredPermission_WhenUserDoesNotHavePermission_CallsFor
189167 . FindComponent < ReadUsersRequiredComponent > ( )
190168 . Instance ;
191169
170+ // No premature decision during initial render.
171+ component . UnauthorizedCount . Should ( ) . Be ( 0 ) ;
172+ component . ForbiddenCount . Should ( ) . Be ( 0 ) ;
173+
174+ state . MarkStale ( ) ;
175+
192176 component . UnauthorizedCount . Should ( ) . Be ( 0 ) ;
193177 component . ForbiddenCount . Should ( ) . Be ( 1 ) ;
194178 }
@@ -286,6 +270,39 @@ public void Dispose_UnsubscribesFromAuthState()
286270 . Should ( ) . Be ( UAuthStateChangeReason . MarkedStale ) ;
287271 }
288272
273+ [ Fact ]
274+ public void AuthStateCleared_WithAuthorizeAttribute_CallsUnauthorized ( )
275+ {
276+ var state = AuthenticatedState ( ) ;
277+
278+ var cut = RenderWithState < AuthenticationRequiredComponent > ( state ) ;
279+
280+ var component = cut
281+ . FindComponent < AuthenticationRequiredComponent > ( )
282+ . Instance ;
283+
284+ component . UnauthorizedCount . Should ( ) . Be ( 0 ) ;
285+
286+ state . Clear ( ) ;
287+
288+ component . UnauthorizedCount . Should ( ) . Be ( 1 ) ;
289+ }
290+
291+ [ Fact ]
292+ public void InitialRender_WithAuthorizeAttribute_DoesNotEvaluateAuthorizationPrematurely ( )
293+ {
294+ var state = UAuthState . Anonymous ( ) ;
295+
296+ var cut = RenderWithState < AuthenticationRequiredComponent > ( state ) ;
297+
298+ var component = cut
299+ . FindComponent < AuthenticationRequiredComponent > ( )
300+ . Instance ;
301+
302+ component . UnauthorizedCount . Should ( ) . Be ( 0 ) ;
303+ component . ForbiddenCount . Should ( ) . Be ( 0 ) ;
304+ }
305+
289306 private IRenderedComponent < CascadingValue < UAuthState > > RenderWithState < TComponent > ( UAuthState state ) where TComponent : IComponent
290307 {
291308 return Render < CascadingValue < UAuthState > > ( parameters =>
0 commit comments