예제 #1
0
    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));
        });
    }
예제 #2
0
    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));
        });
    }