public async Task ProcessAsync_RendersFallbackView_If_MainIsNotFound_AndGetViewReturnsView()
    {
        // Arrange
        var expected     = "Hello from fallback!";
        var bufferScope  = new TestViewBufferScope();
        var partialName  = "_Partial";
        var fallbackName = "_Fallback";
        var model        = new object();
        var viewContext  = GetViewContext();

        var view = new Mock <IView>();

        view.Setup(v => v.RenderAsync(It.IsAny <ViewContext>()))
        .Callback((ViewContext v) =>
        {
            v.Writer.Write(expected);
        })
        .Returns(Task.CompletedTask);

        var viewEngine = new Mock <ICompositeViewEngine>();

        viewEngine.Setup(v => v.GetView(It.IsAny <string>(), partialName, false))
        .Returns(ViewEngineResult.NotFound(partialName, Array.Empty <string>()));
        viewEngine.Setup(v => v.FindView(viewContext, partialName, false))
        .Returns(ViewEngineResult.NotFound(partialName, Array.Empty <string>()));
        viewEngine.Setup(v => v.GetView(It.IsAny <string>(), fallbackName, false))
        .Returns(ViewEngineResult.Found(fallbackName, view.Object));

        var tagHelper = new PartialTagHelper(viewEngine.Object, bufferScope)
        {
            Name         = partialName,
            ViewContext  = viewContext,
            FallbackName = fallbackName
        };
        var tagHelperContext = GetTagHelperContext();
        var output           = GetTagHelperOutput();

        // Act
        await tagHelper.ProcessAsync(tagHelperContext, output);

        // Assert
        var content = HtmlContentUtilities.HtmlContentToString(output.Content, new HtmlTestEncoder());

        Assert.Equal(expected, content);
    }
    public async Task ProcessAsync_UsesPassedInViewData_WhenNotNull()
    {
        // Arrange
        var expected    = "Explicit";
        var bufferScope = new TestViewBufferScope();
        var partialName = "_Partial";
        var model       = new object();
        var viewData    = new ViewDataDictionary(new TestModelMetadataProvider(), new ModelStateDictionary());

        viewData["key"] = expected;
        var viewContext = GetViewContext();

        viewContext.ViewData["key"] = "ViewContext";

        var view = new Mock <IView>();

        view.Setup(v => v.RenderAsync(It.IsAny <ViewContext>()))
        .Callback((ViewContext v) =>
        {
            v.Writer.Write(v.ViewData["key"]);
        })
        .Returns(Task.CompletedTask);

        var viewEngine = new Mock <ICompositeViewEngine>();

        viewEngine.Setup(v => v.GetView(It.IsAny <string>(), partialName, false))
        .Returns(ViewEngineResult.Found(partialName, view.Object));

        var tagHelper = new PartialTagHelper(viewEngine.Object, bufferScope)
        {
            Name        = partialName,
            ViewContext = viewContext,
            ViewData    = viewData,
        };
        var tagHelperContext = GetTagHelperContext();
        var output           = GetTagHelperOutput();

        // Act
        await tagHelper.ProcessAsync(tagHelperContext, output);

        // Assert
        var content = HtmlContentUtilities.HtmlContentToString(output.Content, new HtmlTestEncoder());

        Assert.Equal(expected, content);
    }
    public void ResolveModel_ReturnsViewContextsViewDataModelWhenModelAndForAreNotSet()
    {
        // Arrange
        var expectedModel = new object();
        var viewContext   = GetViewContext();

        viewContext.ViewData.Model = expectedModel;
        var tagHelper = new PartialTagHelper(Mock.Of <ICompositeViewEngine>(), Mock.Of <IViewBufferScope>())
        {
            ViewContext = viewContext
        };

        // Act
        var model = tagHelper.ResolveModel();

        // Assert
        Assert.Same(expectedModel, model);
    }
    public async Task ProcessAsync_UsesViewDataFromContext()
    {
        // Arrange
        var expected    = "Implicit";
        var bufferScope = new TestViewBufferScope();
        var partialName = "_Partial";
        var viewContext = GetViewContext();

        viewContext.ViewData["key"] = expected;

        var view = new Mock <IView>();

        view.Setup(v => v.RenderAsync(It.IsAny <ViewContext>()))
        .Callback((ViewContext v) =>
        {
            v.Writer.Write(v.ViewData["key"]);
        })
        .Returns(Task.CompletedTask);

        var viewEngine = new Mock <ICompositeViewEngine>();

        viewEngine.Setup(v => v.GetView(It.IsAny <string>(), partialName, false))
        .Returns(ViewEngineResult.NotFound(partialName, new[] { partialName }));

        viewEngine.Setup(v => v.FindView(viewContext, partialName, false))
        .Returns(ViewEngineResult.Found(partialName, view.Object));

        var tagHelper = new PartialTagHelper(viewEngine.Object, bufferScope)
        {
            Name        = partialName,
            ViewContext = viewContext,
        };
        var tagHelperContext = GetTagHelperContext();
        var output           = GetTagHelperOutput();

        // Act
        await tagHelper.ProcessAsync(tagHelperContext, output);

        // Assert
        var content = HtmlContentUtilities.HtmlContentToString(output.Content, new HtmlTestEncoder());

        Assert.Equal(expected, content);
    }
    public async Task ProcessAsync_IfOptional_And_ViewIsNotFound_WillNotRenderAnything()
    {
        // Arrange
        var expected    = string.Empty;
        var bufferScope = new TestViewBufferScope();
        var partialName = "_ThisViewDoesNotExists";
        var model       = new object();
        var viewContext = GetViewContext();

        var view = new Mock <IView>();

        view.Setup(v => v.RenderAsync(It.IsAny <ViewContext>()))
        .Callback((ViewContext v) =>
        {
            v.Writer.Write(expected);
        })
        .Returns(Task.CompletedTask);

        var viewEngine = new Mock <ICompositeViewEngine>();

        viewEngine.Setup(v => v.GetView(It.IsAny <string>(), partialName, false))
        .Returns(ViewEngineResult.NotFound(partialName, searchedLocations: Array.Empty <string>()));
        viewEngine.Setup(v => v.FindView(viewContext, partialName, false))
        .Returns(ViewEngineResult.NotFound(partialName, searchedLocations: Array.Empty <string>()));

        var tagHelper = new PartialTagHelper(viewEngine.Object, bufferScope)
        {
            Name        = partialName,
            ViewContext = viewContext,
            Optional    = true
        };
        var tagHelperContext = GetTagHelperContext();
        var output           = GetTagHelperOutput();

        // Act
        await tagHelper.ProcessAsync(tagHelperContext, output);

        // Assert
        var content = HtmlContentUtilities.HtmlContentToString(output.Content, new HtmlTestEncoder());

        Assert.Empty(content);
    }
    public void ResolveModel_ReturnsModelWhenNullValueIsProvided()
    {
        // Regression test for https://github.com/aspnet/Mvc/issues/7667.
        // Arrange
        var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary())
        {
            Model = new object(),
        };
        var tagHelper = new PartialTagHelper(Mock.Of <ICompositeViewEngine>(), Mock.Of <IViewBufferScope>())
        {
            Model    = null,
            ViewData = viewData,
        };

        // Act
        var model = tagHelper.ResolveModel();

        // Assert
        Assert.Null(model);
    }
    public async Task ProcessAsync_DoesNotModifyHtmlFieldPrefix_WhenModelExpressionIsNull()
    {
        // Arrange
        var expected    = "original";
        var bufferScope = new TestViewBufferScope();
        var partialName = "_Partial";
        var model       = new object();
        var viewContext = GetViewContext();

        viewContext.ViewData.Model = model;
        viewContext.ViewData.TemplateInfo.HtmlFieldPrefix = expected;

        var view = new Mock <IView>();

        view.Setup(v => v.RenderAsync(It.IsAny <ViewContext>()))
        .Callback((ViewContext v) =>
        {
            Assert.Equal(expected, v.ViewData.TemplateInfo.HtmlFieldPrefix);
        })
        .Returns(Task.CompletedTask)
        .Verifiable();

        var viewEngine = new Mock <ICompositeViewEngine>();

        viewEngine.Setup(v => v.GetView(It.IsAny <string>(), partialName, false))
        .Returns(ViewEngineResult.Found(partialName, view.Object));

        var tagHelper = new PartialTagHelper(viewEngine.Object, bufferScope)
        {
            Name        = partialName,
            ViewContext = viewContext,
        };
        var tagHelperContext = GetTagHelperContext();
        var output           = GetTagHelperOutput();

        // Act
        await tagHelper.ProcessAsync(tagHelperContext, output);

        // Assert
        view.Verify();
    }
    public void ResolveModel_ThrowsWhenNullModelAndForProvided()
    {
        // Arrange
        var modelMetadataProvider  = new TestModelMetadataProvider();
        var containerModel         = new TestModel();
        var containerModelExplorer = modelMetadataProvider.GetModelExplorerForType(
            typeof(TestModel),
            containerModel);
        var propertyModelExplorer = containerModelExplorer.GetExplorerForProperty(nameof(TestModel.Property));
        var tagHelper             = new PartialTagHelper(Mock.Of <ICompositeViewEngine>(), Mock.Of <IViewBufferScope>())
        {
            Model = null,
            For   = new ModelExpression("Property", propertyModelExplorer),
        };
        var expectedMessage = Resources.FormatPartialTagHelper_InvalidModelAttributes(typeof(PartialTagHelper).FullName, "for", "model");

        // Act & Assert
        var exception = Assert.Throws <InvalidOperationException>(() => tagHelper.ResolveModel());

        Assert.Equal(expectedMessage, exception.Message);
    }
    public async Task ProcessAsync_Throws_If_NotOptional_And_GetViewAndFindReturnNotFoundResults()
    {
        // Arrange
        var bufferScope = new TestViewBufferScope();
        var partialName = "_Partial";
        var expected    = string.Join(Environment.NewLine,
                                      $"The partial view '{partialName}' was not found. The following locations were searched:",
                                      "NotFound1",
                                      "NotFound2",
                                      "NotFound3",
                                      "NotFound4");
        var viewData    = new ViewDataDictionary(new TestModelMetadataProvider(), new ModelStateDictionary());
        var viewContext = GetViewContext();

        var view       = Mock.Of <IView>();
        var viewEngine = new Mock <ICompositeViewEngine>();

        viewEngine.Setup(v => v.GetView(It.IsAny <string>(), partialName, false))
        .Returns(ViewEngineResult.NotFound(partialName, new[] { "NotFound1", "NotFound2" }));

        viewEngine.Setup(v => v.FindView(viewContext, partialName, false))
        .Returns(ViewEngineResult.NotFound(partialName, new[] { $"NotFound3", $"NotFound4" }));

        var tagHelper = new PartialTagHelper(viewEngine.Object, bufferScope)
        {
            Name        = partialName,
            ViewContext = viewContext,
            ViewData    = viewData,
            Optional    = false
        };
        var tagHelperContext = GetTagHelperContext();
        var output           = GetTagHelperOutput();

        // Act & Assert
        var exception = await Assert.ThrowsAsync <InvalidOperationException>(
            () => tagHelper.ProcessAsync(tagHelperContext, output));

        Assert.Equal(expected, exception.Message);
    }
    public void ResolveModel_ReturnsForModelWhenProvided()
    {
        // Arrange
        var expectedModel         = new PropertyModel();
        var modelMetadataProvider = new TestModelMetadataProvider();
        var containerModel        = new TestModel()
        {
            Property = expectedModel
        };
        var containerModelExplorer = modelMetadataProvider.GetModelExplorerForType(
            typeof(TestModel),
            containerModel);
        var propertyModelExplorer = containerModelExplorer.GetExplorerForProperty(nameof(TestModel.Property));
        var tagHelper             = new PartialTagHelper(Mock.Of <ICompositeViewEngine>(), Mock.Of <IViewBufferScope>())
        {
            For = new ModelExpression("Property", propertyModelExplorer),
        };

        // Act
        var model = tagHelper.ResolveModel();

        // Assert
        Assert.Same(expectedModel, model);
    }
    public async Task ProcessAsync_DisposesViewInstance()
    {
        // Arrange
        var bufferScope = new TestViewBufferScope();
        var partialName = "_Partial";
        var viewContext = GetViewContext();

        var disposable = new Mock <IDisposable>();

        disposable.Setup(d => d.Dispose()).Verifiable();
        var view = disposable.As <IView>();

        view.Setup(v => v.RenderAsync(It.IsAny <ViewContext>()))
        .Returns(Task.CompletedTask)
        .Verifiable();

        var viewEngine = new Mock <ICompositeViewEngine>();

        viewEngine.Setup(v => v.GetView(It.IsAny <string>(), partialName, false))
        .Returns(ViewEngineResult.Found(partialName, view.Object));

        var tagHelper = new PartialTagHelper(viewEngine.Object, bufferScope)
        {
            Name        = partialName,
            ViewContext = viewContext,
        };
        var tagHelperContext = GetTagHelperContext();
        var output           = GetTagHelperOutput();

        // Act
        await tagHelper.ProcessAsync(tagHelperContext, output);

        // Assert
        disposable.Verify();
        view.Verify();
    }