public void RespondsToNotificationsFromAuthenticationStateProvider()
        {
            // Arrange: Service
            var services          = new ServiceCollection();
            var authStateProvider = new TestAuthStateProvider()
            {
                CurrentAuthStateTask = Task.FromResult(CreateAuthenticationState(null))
            };

            services.AddSingleton <AuthenticationStateProvider>(authStateProvider);

            // Arrange: Renderer and component, initially rendered
            var renderer  = new TestRenderer(services.BuildServiceProvider());
            var component = new UseCascadingAuthenticationStateComponent();

            renderer.AssignRootComponentId(component);
            component.TriggerRender();
            var receiveAuthStateId = renderer.Batches.Single()
                                     .GetComponentFrames <ReceiveAuthStateComponent>().Single().ComponentId;

            // Act 2: AuthenticationStateProvider issues notification
            authStateProvider.TriggerAuthenticationStateChanged(
                Task.FromResult(CreateAuthenticationState("Bert")));

            // Assert 2: Re-renders content
            Assert.Equal(2, renderer.Batches.Count);
            var batch = renderer.Batches.Last();
            var receiveAuthStateDiff = batch.DiffsByComponentId[receiveAuthStateId].Single();

            Assert.Collection(receiveAuthStateDiff.Edits, edit =>
            {
                Assert.Equal(RenderTreeEditType.UpdateText, edit.Type);
                AssertFrame.Text(
                    batch.ReferenceFrames[edit.ReferenceFrameIndex],
                    "Authenticated: True; Name: Bert; Pending: False; Renders: 2");
            });
        }
예제 #2
0
        public void RendersAuthorizedContentIfAuthorized()
        {
            // Arrange
            var authorizationService = new TestAuthorizationService();

            authorizationService.NextResult = AuthorizationResult.Success();
            var renderer      = CreateTestRenderer(authorizationService);
            var rootComponent = WrapInAuthorizeView(
                authorizedContent: context => builder =>
                builder.AddContent(0, $"You are authenticated as {context.User.Identity.Name}"));

            rootComponent.AuthenticationState = CreateAuthenticationState("Nellie");

            // Act
            renderer.AssignRootComponentId(rootComponent);
            rootComponent.TriggerRender();

            // Assert
            var diff = renderer.Batches.Single().GetComponentDiffs <AuthorizeView>().Single();

            Assert.Collection(diff.Edits, edit =>
            {
                Assert.Equal(RenderTreeEditType.PrependFrame, edit.Type);
                AssertFrame.Text(
                    renderer.Batches.Single().ReferenceFrames[edit.ReferenceFrameIndex],
                    "You are authenticated as Nellie");
            });

            // Assert: The IAuthorizationService was given expected criteria
            Assert.Collection(authorizationService.AuthorizeCalls, call =>
            {
                Assert.Equal("Nellie", call.user.Identity.Name);
                Assert.Null(call.resource);
                Assert.Collection(call.requirements,
                                  req => Assert.IsType <DenyAnonymousAuthorizationRequirement>(req));
            });
        }
        public void CanRenderComponentByTypeWithParameters()
        {
            // Arrange
            var instance        = new DynamicComponent();
            var renderer        = new TestRenderer();
            var childParameters = new Dictionary <string, object>
            {
                { nameof(TestComponent.IntProp), 123 },
                { nameof(TestComponent.ChildContent), (RenderFragment)(builder =>
                    {
                        builder.AddContent(0, "This is some child content");
                    }) },
            };
            var parameters = ParameterView.FromDictionary(new Dictionary <string, object>
            {
                { nameof(DynamicComponent.Type), typeof(TestComponent) },
                { nameof(DynamicComponent.Parameters), childParameters },
            });

            // Act
            renderer.RenderRootComponent(
                renderer.AssignRootComponentId(instance),
                parameters);

            // Assert
            var batch = renderer.Batches.Single();

            // It renders a reference to the child component with its parameters
            AssertFrame.Component <TestComponent>(batch.ReferenceFrames[0], 4, 0);
            AssertFrame.Attribute(batch.ReferenceFrames[1], nameof(TestComponent.IntProp), 123, 1);
            AssertFrame.Attribute(batch.ReferenceFrames[2], nameof(TestComponent.ChildContent), 1);

            // The child component itself is rendered
            AssertFrame.Text(batch.ReferenceFrames[4], "Hello from TestComponent with IntProp=123", 0);
            AssertFrame.Text(batch.ReferenceFrames[5], "This is some child content", 0);
        }
예제 #4
0
        public void RendersAuthorizingUntilAuthorizationCompleted()
        {
            // Arrange
            var @event = new ManualResetEventSlim();
            var authorizationService = new TestAuthorizationService();

            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>();

            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();
            authTcs.SetResult(CreateAuthenticationState("Monsieur").Result);

            // We need to wait here because the continuations of SetResult will be scheduled to run 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.RemoveFrame, edit.Type);
                Assert.Equal(0, edit.SiblingIndex);
            },
                              edit =>
            {
                Assert.Equal(RenderTreeEditType.PrependFrame, 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));
            });
        }