public async Task RendersAuthorizingUntilAuthorizationCompletedAsync() { // Covers https://github.com/dotnet/aspnetcore/pull/31794 // Arrange var authorizationService = new TestAsyncAuthorizationService(); authorizationService.NextResult = AuthorizationResult.Success(); var renderer = CreateTestRenderer(authorizationService); renderer.OnUpdateDisplayComplete = () => { }; var rootComponent = WrapInAuthorizeView( authorizing: builder => builder.AddContent(0, "Auth pending..."), authorized: context => builder => builder.AddContent(0, $"Hello, {context.User.Identity.Name}!")); var authTcs = new TaskCompletionSource <AuthenticationState>(); rootComponent.AuthenticationState = authTcs.Task; // Act/Assert 1: Auth pending renderer.AssignRootComponentId(rootComponent); rootComponent.TriggerRender(); var batch1 = Assert.Single(renderer.Batches); var authorizeViewComponentId = Assert.Single(batch1.GetComponentFrames <AuthorizeView>()).ComponentId; var diff1 = Assert.Single(batch1.DiffsByComponentId[authorizeViewComponentId]); Assert.Collection(diff1.Edits, edit => { Assert.Equal(RenderTreeEditType.PrependFrame, edit.Type); AssertFrame.Text( batch1.ReferenceFrames[edit.ReferenceFrameIndex], "Auth pending..."); }); // We need to do this because the continuation from the TCS might run asynchronously // (This wouldn't happen under the sync context or in wasm) var renderTcs = new TaskCompletionSource(); renderer.OnUpdateDisplayComplete = () => renderTcs.SetResult(); authTcs.SetResult(CreateAuthenticationState("Monsieur").Result); await renderTcs.Task; Assert.Equal(2, renderer.Batches.Count); var batch2 = renderer.Batches[1]; var diff2 = Assert.Single(batch2.DiffsByComponentId[authorizeViewComponentId]); Assert.Collection(diff2.Edits, edit => { Assert.Equal(RenderTreeEditType.UpdateText, edit.Type); Assert.Equal(0, edit.SiblingIndex); AssertFrame.Text( batch2.ReferenceFrames[edit.ReferenceFrameIndex], "Hello, Monsieur!"); }); // Assert: The IAuthorizationService was given expected criteria Assert.Collection(authorizationService.AuthorizeCalls, call => { Assert.Equal("Monsieur", call.user.Identity.Name); Assert.Null(call.resource); Assert.Collection(call.requirements, req => Assert.IsType <DenyAnonymousAuthorizationRequirement>(req)); }); }
public void RendersAuthorizingUntilAuthorizationCompletedAsync() { // Covers https://github.com/dotnet/aspnetcore/pull/31794 // Arrange var @event = new ManualResetEventSlim(); var authorizationService = new TestAsyncAuthorizationService(); authorizationService.NextResult = AuthorizationResult.Success(); var renderer = CreateTestRenderer(authorizationService); renderer.OnUpdateDisplayComplete = () => { @event.Set(); }; var rootComponent = WrapInAuthorizeView( authorizing: builder => builder.AddContent(0, "Auth pending..."), authorized: context => builder => builder.AddContent(0, $"Hello, {context.User.Identity.Name}!")); var authTcs = new TaskCompletionSource <AuthenticationState>(); // Complete the authentication beforehand authTcs.SetResult(CreateAuthenticationState("Monsieur").Result); rootComponent.AuthenticationState = authTcs.Task; // Act/Assert 1: Auth pending renderer.AssignRootComponentId(rootComponent); rootComponent.TriggerRender(); var batch1 = renderer.Batches.Single(); var authorizeViewComponentId = batch1.GetComponentFrames <AuthorizeView>().Single().ComponentId; var diff1 = batch1.DiffsByComponentId[authorizeViewComponentId].Single(); Assert.Collection(diff1.Edits, edit => { Assert.Equal(RenderTreeEditType.PrependFrame, edit.Type); AssertFrame.Text( batch1.ReferenceFrames[edit.ReferenceFrameIndex], "Auth pending..."); }); // Act/Assert 2: Auth process completes asynchronously @event.Reset(); // Wait for authorization to complete asynchronously @event.Wait(Timeout); Assert.Equal(2, renderer.Batches.Count); var batch2 = renderer.Batches[1]; var diff2 = batch2.DiffsByComponentId[authorizeViewComponentId].Single(); Assert.Collection(diff2.Edits, edit => { Assert.Equal(RenderTreeEditType.UpdateText, edit.Type); Assert.Equal(0, edit.SiblingIndex); AssertFrame.Text( batch2.ReferenceFrames[edit.ReferenceFrameIndex], "Hello, Monsieur!"); }); // Assert: The IAuthorizationService was given expected criteria Assert.Collection(authorizationService.AuthorizeCalls, call => { Assert.Equal("Monsieur", call.user.Identity.Name); Assert.Null(call.resource); Assert.Collection(call.requirements, req => Assert.IsType <DenyAnonymousAuthorizationRequirement>(req)); }); }