// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using System.ComponentModel.DataAnnotations; using System.Globalization; using System.IO; using System.Threading.Tasks; using Microsoft.AspNet.Mvc.ModelBinding; using Microsoft.AspNet.PipelineCore; using Microsoft.AspNet.Routing; using Microsoft.AspNet.Security.DataProtection; using Microsoft.Framework.OptionsModel; using Moq; namespace Microsoft.AspNet.Mvc.Rendering { public class DefaultTemplatesUtilities { public class ObjectTemplateModel { public ObjectTemplateModel() { ComplexInnerModel = new object(); } public string Property1 { get; set; } public string Property2 { get; set; } public object ComplexInnerModel { get; set; } } public class ObjectWithScaffoldColumn { public string Property1 { get; set; } [ScaffoldColumn(false)] public string Property2 { get; set; } [ScaffoldColumn(true)] public string Property3 { get; set; } } public static HtmlHelper GetHtmlHelper() { return GetHtmlHelper(model: null); } public static HtmlHelper GetHtmlHelper(IUrlHelper urlHelper) { return GetHtmlHelper( model: null, urlHelper: urlHelper, viewEngine: CreateViewEngine(), provider: CreateModelMetadataProvider()); } public static HtmlHelper GetHtmlHelper(IHtmlGenerator htmlGenerator) { var metadataProvider = CreateModelMetadataProvider(); return GetHtmlHelper( new ViewDataDictionary(metadataProvider), CreateUrlHelper(), CreateViewEngine(), metadataProvider, innerHelperWrapper: null, htmlGenerator: htmlGenerator); } public static HtmlHelper GetHtmlHelper(ViewDataDictionary viewData) { return GetHtmlHelper( viewData, CreateUrlHelper(), CreateViewEngine(), CreateModelMetadataProvider(), innerHelperWrapper: null, htmlGenerator: null); } public static HtmlHelper GetHtmlHelper(TModel model) { return GetHtmlHelper(model, CreateViewEngine()); } public static HtmlHelper GetHtmlHelper(IModelMetadataProvider provider) { return GetHtmlHelper(model: null, provider: provider); } public static HtmlHelper GetHtmlHelper(TModel model, IModelMetadataProvider provider) { return GetHtmlHelper(model, CreateUrlHelper(), CreateViewEngine(), provider); } public static HtmlHelper GetHtmlHelper(TModel model, ICompositeViewEngine viewEngine) { return GetHtmlHelper(model, CreateUrlHelper(), viewEngine, CreateModelMetadataProvider()); } public static HtmlHelper GetHtmlHelper( TModel model, ICompositeViewEngine viewEngine, Func innerHelperWrapper) { return GetHtmlHelper( model, CreateUrlHelper(), viewEngine, CreateModelMetadataProvider(), innerHelperWrapper); } public static HtmlHelper GetHtmlHelper( TModel model, IUrlHelper urlHelper, ICompositeViewEngine viewEngine, IModelMetadataProvider provider) { return GetHtmlHelper(model, urlHelper, viewEngine, provider, innerHelperWrapper: null); } public static HtmlHelper GetHtmlHelper( TModel model, IUrlHelper urlHelper, ICompositeViewEngine viewEngine, IModelMetadataProvider provider, Func innerHelperWrapper) { var viewData = new ViewDataDictionary(provider); viewData.Model = model; return GetHtmlHelper(viewData, urlHelper, viewEngine, provider, innerHelperWrapper, htmlGenerator: null); } private static HtmlHelper GetHtmlHelper( ViewDataDictionary viewData, IUrlHelper urlHelper, ICompositeViewEngine viewEngine, IModelMetadataProvider provider, Func innerHelperWrapper, IHtmlGenerator htmlGenerator) { var httpContext = new DefaultHttpContext(); var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); var serviceProvider = new Mock(); serviceProvider .Setup(s => s.GetService(typeof(ICompositeViewEngine))) .Returns(viewEngine); serviceProvider .Setup(s => s.GetService(typeof(IUrlHelper))) .Returns(urlHelper); serviceProvider .Setup(s => s.GetService(typeof(IViewComponentHelper))) .Returns(new Mock().Object); httpContext.RequestServices = serviceProvider.Object; if (htmlGenerator == null) { var actionBindingContext = new ActionBindingContext( actionContext, provider, Mock.Of(), Mock.Of(), Mock.Of(), new DataAnnotationsModelValidatorProvider()); var actionBindingContextProvider = new Mock(); actionBindingContextProvider .Setup(c => c.GetActionBindingContextAsync(It.IsAny())) .Returns(Task.FromResult(actionBindingContext)); htmlGenerator = new DefaultHtmlGenerator( actionBindingContextProvider.Object, GetAntiForgeryInstance(), provider, urlHelper); } // TemplateRenderer will Contextualize this transient service. var innerHelper = (IHtmlHelper)new HtmlHelper(htmlGenerator, viewEngine, provider); if (innerHelperWrapper != null) { innerHelper = innerHelperWrapper(innerHelper); } serviceProvider .Setup(s => s.GetService(typeof(IHtmlHelper))) .Returns(() => innerHelper); var htmlHelper = new HtmlHelper(htmlGenerator, viewEngine, provider); var viewContext = new ViewContext(actionContext, Mock.Of(), viewData, new StringWriter()); htmlHelper.Contextualize(viewContext); return htmlHelper; } public static string FormatOutput(IHtmlHelper helper, object model) { var metadata = helper.MetadataProvider.GetMetadataForType(() => model, model.GetType()); return FormatOutput(metadata); } private static ICompositeViewEngine CreateViewEngine() { var view = new Mock(); view .Setup(v => v.RenderAsync(It.IsAny())) .Callback(async (ViewContext v) => { view.ToString(); await v.Writer.WriteAsync(FormatOutput(v.ViewData.ModelMetadata)); }) .Returns(Task.FromResult(0)); var viewEngine = new Mock(); viewEngine .Setup(v => v.FindPartialView(It.IsAny(), It.IsAny())) .Returns(ViewEngineResult.Found("MyView", view.Object)); return viewEngine.Object; } private static AntiForgery GetAntiForgeryInstance() { var claimExtractor = new Mock(); var dataProtectionProvider = new Mock(); var additionalDataProvider = new Mock(); var optionsAccessor = new Mock>(); optionsAccessor.SetupGet(o => o.Options).Returns(new MvcOptions()); return new AntiForgery(claimExtractor.Object, dataProtectionProvider.Object, additionalDataProvider.Object, optionsAccessor.Object); } private static string FormatOutput(ModelMetadata metadata) { return string.Format(CultureInfo.InvariantCulture, "Model = {0}, ModelType = {1}, PropertyName = {2}, SimpleDisplayText = {3}", metadata.Model ?? "(null)", metadata.ModelType == null ? "(null)" : metadata.ModelType.FullName, metadata.PropertyName ?? "(null)", metadata.SimpleDisplayText ?? "(null)"); } private static IUrlHelper CreateUrlHelper() { return Mock.Of(); } private static IModelMetadataProvider CreateModelMetadataProvider() { return new DataAnnotationsModelMetadataProvider(); } } }