Example #1
0
        public void GetAvailableDisplayModesForContextWithRestrictingPageElements()
        {
            // Arrange
            Mock <HttpContextBase> httpContext = new Mock <HttpContextBase>(MockBehavior.Strict);
            var displayModeProvider            = new DisplayModeProvider();

            displayModeProvider.Modes.Clear();
            var displayMode1 = new Mock <IDisplayMode>(MockBehavior.Strict);

            displayMode1.Setup(d => d.CanHandleContext(It.IsAny <HttpContextBase>())).Returns(true);
            displayModeProvider.Modes.Add(displayMode1.Object);

            var displayMode2 = new Mock <IDisplayMode>(MockBehavior.Strict);

            displayMode2.Setup(d => d.CanHandleContext(It.IsAny <HttpContextBase>())).Returns(false);
            displayModeProvider.Modes.Add(displayMode2.Object);

            var displayMode3 = new Mock <IDisplayMode>(MockBehavior.Strict);

            displayMode3.Setup(d => d.CanHandleContext(It.IsAny <HttpContextBase>())).Returns(true);
            displayModeProvider.Modes.Add(displayMode3.Object);

            // Act
            var availableDisplayModes = displayModeProvider.GetAvailableDisplayModesForContext(httpContext.Object, displayMode2.Object, requireConsistentDisplayMode: true).ToList();

            // Assert
            var availableDisplayMode = Assert.Single(availableDisplayModes);

            Assert.Equal(displayMode3.Object, availableDisplayMode);
        }
        public void GetDisplayModesForRequestReturnsNullIfNoDisplayModesHandleRequest()
        {
            // Arrange
            Mock <HttpContextBase> httpContext = new Mock <HttpContextBase>(MockBehavior.Strict);
            var displayModeProvider            = new DisplayModeProvider();

            displayModeProvider.Modes.Clear();
            var displayMode1 = new Mock <IDisplayMode>(MockBehavior.Strict);

            displayMode1.Setup(d => d.CanHandleContext(It.IsAny <HttpContextBase>())).Returns(false);
            displayModeProvider.Modes.Add(displayMode1.Object);

            var displayMode2 = new Mock <IDisplayMode>(MockBehavior.Strict);

            displayMode2.Setup(d => d.CanHandleContext(It.IsAny <HttpContextBase>())).Returns(false);
            displayModeProvider.Modes.Add(displayMode2.Object);

            var displayMode3 = new Mock <IDisplayMode>(MockBehavior.Strict);

            displayMode3.Setup(d => d.CanHandleContext(It.IsAny <HttpContextBase>())).Returns(false);
            displayModeProvider.Modes.Add(displayMode3.Object);

            // Act
            DisplayInfo displayModeForRequest = displayModeProvider.GetDisplayInfoForVirtualPath("path", httpContext.Object, path => false, currentDisplayMode: null);

            // Assert
            Assert.Null(displayModeForRequest);
        }
        public void GetDisplayInfoForVirtualPathWithoutConsistentDisplayModeIgnoresCurrentDisplayMode()
        {
            // Arrange
            Mock <HttpContextBase> httpContext = new Mock <HttpContextBase>(MockBehavior.Strict);
            var displayModeProvider            = new DisplayModeProvider();

            displayModeProvider.Modes.Clear();
            var displayMode1 = new Mock <IDisplayMode>(MockBehavior.Strict);

            displayMode1.Setup(d => d.CanHandleContext(It.IsAny <HttpContextBase>())).Returns(true);
            displayModeProvider.Modes.Add(displayMode1.Object);

            var displayMode2 = new Mock <IDisplayMode>(MockBehavior.Strict);

            displayMode2.Setup(d => d.CanHandleContext(It.IsAny <HttpContextBase>())).Returns(false);
            displayModeProvider.Modes.Add(displayMode2.Object);

            var displayMode3 = new Mock <IDisplayMode>(MockBehavior.Strict);

            displayMode3.Setup(d => d.CanHandleContext(It.IsAny <HttpContextBase>())).Returns(true);
            displayModeProvider.Modes.Add(displayMode3.Object);

            var displayInfo = new DisplayInfo("Foo", displayMode3.Object);
            Func <string, bool> fileExists = path => true;

            displayMode1.Setup(d => d.GetDisplayInfo(httpContext.Object, "path", fileExists)).Returns(displayInfo);

            // Act
            DisplayInfo result = displayModeProvider.GetDisplayInfoForVirtualPath("path", httpContext.Object, fileExists, currentDisplayMode: displayMode1.Object,
                                                                                  requireConsistentDisplayMode: false);

            // Assert
            Assert.Same(displayInfo, result);
        }
        public void GetDisplayInfoForVirtualPathReturnsDisplayInfoFromFirstDisplayModeToHandleRequest()
        {
            // Arrange
            var displayModeProvider = new DisplayModeProvider();

            displayModeProvider.Modes.Clear();
            var displayMode1 = new Mock <IDisplayMode>(MockBehavior.Strict);

            displayMode1.Setup(d => d.CanHandleContext(It.IsAny <HttpContextBase>())).Returns(false);
            displayModeProvider.Modes.Add(displayMode1.Object);

            var displayMode2 = new Mock <IDisplayMode>(MockBehavior.Strict);

            displayMode2.Setup(d => d.CanHandleContext(It.IsAny <HttpContextBase>())).Returns(false);
            displayModeProvider.Modes.Add(displayMode2.Object);

            var displayMode3 = new Mock <IDisplayMode>(MockBehavior.Strict);

            displayMode3.Setup(d => d.CanHandleContext(It.IsAny <HttpContextBase>())).Returns(true);
            displayModeProvider.Modes.Add(displayMode3.Object);

            Mock <HttpContextBase> httpContext = new Mock <HttpContextBase>(MockBehavior.Strict);

            var expected = new DisplayInfo("Foo", displayMode3.Object);
            Func <string, bool> fileExists = path => true;

            displayMode3.Setup(d => d.GetDisplayInfo(httpContext.Object, "path", fileExists)).Returns(expected);

            // Act
            DisplayInfo result = displayModeProvider.GetDisplayInfoForVirtualPath("path", httpContext.Object, fileExists, currentDisplayMode: null);

            // Assert
            Assert.Same(expected, result);
        }
        public void GetDisplayInfoForVirtualPathWithConsistentDisplayModeBeginsSearchAtCurrentDisplayMode()
        {
            // Arrange
            Mock<HttpContextBase> httpContext = new Mock<HttpContextBase>(MockBehavior.Strict);

            var displayModeProvider = new DisplayModeProvider();
            displayModeProvider.Modes.Clear();
            var displayMode1 = new Mock<IDisplayMode>(MockBehavior.Strict);
            displayMode1.Setup(d => d.CanHandleContext(It.IsAny<HttpContextBase>())).Returns(true);
            displayModeProvider.Modes.Add(displayMode1.Object);

            var displayMode2 = new Mock<IDisplayMode>(MockBehavior.Strict);
            displayMode2.Setup(d => d.CanHandleContext(It.IsAny<HttpContextBase>())).Returns(false);
            displayModeProvider.Modes.Add(displayMode2.Object);

            var displayMode3 = new Mock<IDisplayMode>(MockBehavior.Strict);
            displayMode3.Setup(d => d.CanHandleContext(It.IsAny<HttpContextBase>())).Returns(true);
            displayModeProvider.Modes.Add(displayMode3.Object);

            var displayInfo = new DisplayInfo("Foo", displayMode3.Object);
            Func<string, bool> fileExists = path => true;
            displayMode3.Setup(d => d.GetDisplayInfo(httpContext.Object, "path", fileExists)).Returns(displayInfo);

            // Act
            DisplayInfo result = displayModeProvider.GetDisplayInfoForVirtualPath("path", httpContext.Object, fileExists, currentDisplayMode: displayMode2.Object,
                requireConsistentDisplayMode: true);

            // Assert
            Assert.Same(displayInfo, result);
        }
        public void GetDisplayInfoForVirtualPathReturnsDisplayInfoFromFirstDisplayModeToHandleRequest()
        {
            // Arrange
            var displayModeProvider = new DisplayModeProvider();
            displayModeProvider.Modes.Clear();
            var displayMode1 = new Mock<IDisplayMode>(MockBehavior.Strict);
            displayMode1.Setup(d => d.CanHandleContext(It.IsAny<HttpContextBase>())).Returns(false);
            displayModeProvider.Modes.Add(displayMode1.Object);

            var displayMode2 = new Mock<IDisplayMode>(MockBehavior.Strict);
            displayMode2.Setup(d => d.CanHandleContext(It.IsAny<HttpContextBase>())).Returns(false);
            displayModeProvider.Modes.Add(displayMode2.Object);

            var displayMode3 = new Mock<IDisplayMode>(MockBehavior.Strict);
            displayMode3.Setup(d => d.CanHandleContext(It.IsAny<HttpContextBase>())).Returns(true);
            displayModeProvider.Modes.Add(displayMode3.Object);

            Mock<HttpContextBase> httpContext = new Mock<HttpContextBase>(MockBehavior.Strict);

            var expected = new DisplayInfo("Foo", displayMode3.Object);
            Func<string, bool> fileExists = path => true;
            displayMode3.Setup(d => d.GetDisplayInfo(httpContext.Object, "path", fileExists)).Returns(expected);

            // Act
            DisplayInfo result = displayModeProvider.GetDisplayInfoForVirtualPath("path", httpContext.Object, fileExists, currentDisplayMode: null);

            // Assert
            Assert.Same(expected, result);
        }
Example #7
0
        public void MatchRequestSetsDisplayModeOfFirstMatchPerContext()
        {
            // Arrange
            var objectFactory = new HashyBuildManager(
                new string[] { "~/page.Mobile.aspx", "~/nonMobile.aspx" }
                );
            var mockContext = new Mock <HttpContextBase>();

            mockContext.Setup(context => context.Items).Returns(new Hashtable());
            mockContext.Setup(c => c.Request.Browser.IsMobileDevice).Returns(true);
            mockContext.Setup(c => c.Request.Cookies).Returns(new HttpCookieCollection());
            mockContext.Setup(c => c.Response.Cookies).Returns(new HttpCookieCollection());

            var displayModeProvider = new DisplayModeProvider();

            // Act
            WebPageMatch mobileMatch = WebPageRoute.MatchRequest(
                "page.aspx",
                new string[] { "aspx" },
                objectFactory.Exists,
                mockContext.Object,
                displayModeProvider
                );

            // Assert
            Assert.NotNull(mobileMatch.MatchedPath);
            Assert.Equal(
                DisplayModeProvider.MobileDisplayModeId,
                DisplayModeProvider.GetDisplayMode(mockContext.Object).DisplayModeId
                );
        }
Example #8
0
        public void MatchRequestDoesNotSetDisplayModeIfNoMatch()
        {
            // Arrange
            var objectFactory = new HashyBuildManager(new string[] { "~/page.Mobile.aspx" });
            var mockContext   = new Mock <HttpContextBase>();

            mockContext.Setup(context => context.Items).Returns(new Hashtable());
            mockContext.Setup(c => c.Request.Browser.IsMobileDevice).Returns(true);
            mockContext.Setup(c => c.Request.Cookies).Returns(new HttpCookieCollection());
            mockContext.Setup(c => c.Response.Cookies).Returns(new HttpCookieCollection());

            var displayModeProvider = new DisplayModeProvider();
            var displayMode         = new Mock <IDisplayMode>(MockBehavior.Strict);

            displayMode.Setup(d => d.CanHandleContext(mockContext.Object)).Returns(false);
            displayModeProvider.Modes.Add(displayMode.Object);

            // Act
            WebPageMatch smartyMatch = WebPageRoute.MatchRequest(
                "notThere.aspx",
                new string[] { "aspx" },
                objectFactory.Exists,
                mockContext.Object,
                displayModeProvider
                );

            // Assert
            Assert.Null(DisplayModeProvider.GetDisplayMode(mockContext.Object));
        }
Example #9
0
    public static void RegisterDisplayModes(DisplayModeProvider provider)
    {
        // INFO: Allows to name views/partials/masters like viewname.iphone.cshtml, and MVC will choose this automatically

        // INFO: Lets remove the default "Mobile" mode, since it's pretty useless
        var mobileDefault = DisplayModeProvider.Instance.Modes.First(m => m.DisplayModeId == "Mobile");

        if (mobileDefault != null)
        {
            DisplayModeProvider.Instance.Modes.Remove(mobileDefault);
        }
        // INFO: Now add one that actually works
        provider.Modes.Insert(0,
                              new DefaultDisplayMode("Mobile")
        {
            ContextCondition = (context => (!string.IsNullOrEmpty(context.GetOverriddenUserAgent()) && Regex.IsMatch(context.GetOverriddenUserAgent(), @"mobile|android|kindle|silk|midp", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)))
        });

        // INFO: Order from least to most important (since we insert at position 0)
        provider.Modes.Insert(1,
                              new DefaultDisplayMode("Win8")
        {
            ContextCondition = (context => (!string.IsNullOrEmpty(context.GetOverriddenUserAgent()) && context.GetOverriddenUserAgent().IndexOf("Windows NT 6.2", StringComparison.OrdinalIgnoreCase) >= 0))
        });
    }
Example #10
0
        private string GetPathFromGeneralName(ControllerContext controllerContext, IEnumerable <ViewLocation> locations, IDisplayMode displayMode, string name, string controllerName, string areaName, string cacheKey, out IList <string> searchedLocations)
        {
            searchedLocations = new List <string>();

            // Iterate through the locations.

            foreach (var location in locations)
            {
                var virtualPath = location.Format(name, controllerName, areaName);

                var virtualPathDisplayInfo = DisplayModeProvider.GetDisplayInfoForVirtualPath(virtualPath, controllerContext.HttpContext, path => FileExists(controllerContext, path), controllerContext.DisplayMode);
                if (virtualPathDisplayInfo != null)
                {
                    // Found a path for a view for a display mode.  Cache it against the most specific display mode.

                    var resolvedVirtualPath = virtualPathDisplayInfo.FilePath;
                    ViewLocationCache.InsertViewLocation(controllerContext.HttpContext, AppendDisplayModeToCacheKey(cacheKey, displayMode.DisplayModeId), resolvedVirtualPath);

                    if (controllerContext.DisplayMode == null)
                    {
                        controllerContext.DisplayMode = virtualPathDisplayInfo.DisplayMode;
                    }

                    searchedLocations.Clear();
                    return(resolvedVirtualPath);
                }

                searchedLocations.Add(virtualPath);
            }

            // Even though it does not exist add it to the cache so that all subsequent lookups don't have to check again.

            ViewLocationCache.InsertViewLocation(controllerContext.HttpContext, AppendDisplayModeToCacheKey(cacheKey, displayMode.DisplayModeId), DoesNotExist);
            return(string.Empty);
        }
Example #11
0
        public static void Register(DisplayModeProvider instance)
        {
            var builder = new DisplayModeMatrixBuilder();

            var profiles = builder
                           .AddOptionalFactor("Device", o => o
                                              .Evidence("Tablet", x => Regex.IsMatch(x.GetOverriddenUserAgent(), @"\b(iPad|Tablet)\b"))
                                              .Evidence("Mobile", x => x.GetOverriddenBrowser().IsMobileDevice))
                           .AddOptionalFactor("Theme", o => o
                                              .Evidence("Dark", x => x.Request.Cookies.AllKeys.Contains("Theme") && x.Request.Cookies["Theme"].Value == "dark")
                                              .Evidence("Light", x => x.Request.Cookies.AllKeys.Contains("Theme") && x.Request.Cookies["Theme"].Value == "light"))
                           .AddOptionalFactor("Preview", o => o
                                              .Evidence("Preview", x => x.Request.Cookies.AllKeys.Contains("Preview")))
                           .Build();

            instance.Modes.Clear();

            foreach (var profile in profiles)
            {
                instance.Modes.Add(new DefaultDisplayMode(profile.Name)
                {
                    ContextCondition = profile.ContextCondition
                });
            }

            instance.Modes.Add(new DefaultDisplayMode());
        }
        public void GetAvailableDisplayModesReturnsOnlyModesThatCanHandleContext()
        {
            // Arrange
            Mock <HttpContextBase> httpContext = new Mock <HttpContextBase>(MockBehavior.Strict);
            var displayModeProvider            = new DisplayModeProvider();

            displayModeProvider.Modes.Clear();
            var displayMode1 = new Mock <IDisplayMode>(MockBehavior.Strict);

            displayMode1.Setup(d => d.CanHandleContext(It.IsAny <HttpContextBase>())).Returns(false);
            displayModeProvider.Modes.Add(displayMode1.Object);

            var displayMode2 = new Mock <IDisplayMode>(MockBehavior.Strict);

            displayMode2.Setup(d => d.CanHandleContext(It.IsAny <HttpContextBase>())).Returns(true);
            displayModeProvider.Modes.Add(displayMode2.Object);

            var displayMode3 = new Mock <IDisplayMode>(MockBehavior.Strict);

            displayMode3.Setup(d => d.CanHandleContext(It.IsAny <HttpContextBase>())).Returns(false);
            displayModeProvider.Modes.Add(displayMode3.Object);

            // Act
            var availableDisplayModes = displayModeProvider.GetAvailableDisplayModesForContext(httpContext.Object, displayMode1.Object, requireConsistentDisplayMode: false).ToList();

            // Assert
            Assert.Equal(1, availableDisplayModes.Count);
            Assert.Equal(displayMode2.Object, availableDisplayModes[0]);
        }
Example #13
0
        private string GetPath(ControllerContext controllerContext, string[] locations, string[] areaLocations, string locationsPropertyName, string name, string controllerName, string theme, string cacheKeyPrefix, bool useCache, out string[] searchedLocations)
        {
            searchedLocations = EmptyLocations;

            if (string.IsNullOrEmpty(name))
            {
                return(string.Empty);
            }

            string areaName = GetAreaName(controllerContext.RouteData);

            bool usingAreas = !string.IsNullOrEmpty(areaName);

            var viewLocations = GetViewLocations(locations, usingAreas ? areaLocations : null);

            if (!viewLocations.Any())
            {
                throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, "Properties cannot be null or empty - {0}", locationsPropertyName));
            }

            bool nameRepresentsPath = IsSpecificPath(name);

            string cacheKey = CreateCacheKey(cacheKeyPrefix, name, nameRepresentsPath ? string.Empty : controllerName, areaName, theme);

            if (useCache)
            {
                // Only look at cached display modes that can handle the context.
                IEnumerable <IDisplayMode> possibleDisplayModes = DisplayModeProvider.GetAvailableDisplayModesForContext(controllerContext.HttpContext, controllerContext.DisplayMode);

                foreach (IDisplayMode displayMode in possibleDisplayModes)
                {
                    string cachedLocation = ViewLocationCache.GetViewLocation(controllerContext.HttpContext, AppendDisplayModeToCacheKey(cacheKey, displayMode.DisplayModeId));

                    if (cachedLocation == null)
                    {
                        // If any matching display mode location is not in the cache, fall back to the uncached behavior, which will repopulate all of our caches.
                        return(null);
                    }

                    // A non-empty cachedLocation indicates that we have a matching file on disk. Return that result.
                    if (cachedLocation.Length > 0)
                    {
                        if (controllerContext.DisplayMode == null)
                        {
                            controllerContext.DisplayMode = displayMode;
                        }

                        return(cachedLocation);
                    }

                    // An empty cachedLocation value indicates that we don't have a matching file on disk. Keep going down the list of possible display modes.
                }

                // GetPath is called again without using the cache.
                return(null);
            }

            return(nameRepresentsPath ? GetPathFromSpecificName(controllerContext, name, cacheKey, ref searchedLocations) : GetPathFromGeneralName(controllerContext, viewLocations, name, controllerName, areaName, theme, cacheKey, ref searchedLocations));
        }
Example #14
0
        protected virtual string GetPathFromGeneralName(ControllerContext controllerContext, List <ViewLocation> locations, string name, string controllerName, string areaName, string theme, string cacheKey, ref string[] searchedLocations)
        {
            string result = string.Empty;

            searchedLocations = new string[locations.Count];

            for (int index = 0; index < locations.Count; index++)
            {
                var location = locations[index];

                string virtualPath = location.Format(name, controllerName, areaName, theme);

                var virtualPathDisplayInfo = DisplayModeProvider.GetDisplayInfoForVirtualPath(virtualPath, controllerContext.HttpContext, path => FileExists(controllerContext, path), controllerContext.DisplayMode);

                if (virtualPathDisplayInfo != null)
                {
                    string resolvedVirtualPath = virtualPathDisplayInfo.FilePath;

                    searchedLocations = EmptyLocations;

                    result = resolvedVirtualPath;

                    ViewLocationCache.InsertViewLocation(controllerContext.HttpContext, AppendDisplayModeToCacheKey(cacheKey, virtualPathDisplayInfo.DisplayMode.DisplayModeId), result);

                    if (controllerContext.DisplayMode == null)
                    {
                        controllerContext.DisplayMode = virtualPathDisplayInfo.DisplayMode;
                    }

                    // Populate the cache for all other display modes. We want to cache both file system hits and misses so that we can distinguish
                    // in future requests whether a file's status was evicted from the cache (null value) or if the file doesn't exist (empty string).
                    IEnumerable <IDisplayMode> allDisplayModes = DisplayModeProvider.Modes;

                    foreach (var displayMode in allDisplayModes)
                    {
                        if (displayMode.DisplayModeId != virtualPathDisplayInfo.DisplayMode.DisplayModeId)
                        {
                            var displayInfoToCache = displayMode.GetDisplayInfo(controllerContext.HttpContext, virtualPath, virtualPathExists: path => FileExists(controllerContext, path));

                            string cacheValue = string.Empty;

                            if (displayInfoToCache?.FilePath != null)
                            {
                                cacheValue = displayInfoToCache.FilePath;
                            }

                            ViewLocationCache.InsertViewLocation(controllerContext.HttpContext, AppendDisplayModeToCacheKey(cacheKey, displayMode.DisplayModeId), cacheValue);
                        }
                    }

                    break;
                }

                searchedLocations[index] = virtualPath;
            }

            return(result);
        }
Example #15
0
        private string GetPathFromGeneralName(ControllerContext controllerContext, List <ViewLocation> locations,
                                              string name, string controllerName, string areaName, string rootFolder, string cacheKey,
                                              ref string[] searchedLocations)
        {
            var result = string.Empty;

            searchedLocations = new string[locations.Count];

            for (var i = 0; i < locations.Count; i++)
            {
                var location               = locations[i];
                var virtualPath            = location.Format(name, controllerName, areaName, rootFolder);
                var virtualPathDisplayInfo = DisplayModeProvider.GetDisplayInfoForVirtualPath(virtualPath,
                                                                                              controllerContext.HttpContext, path => FileExists(controllerContext, path),
                                                                                              controllerContext.DisplayMode);

                if (virtualPathDisplayInfo != null)
                {
                    var resolvedVirtualPath = virtualPathDisplayInfo.FilePath;

                    searchedLocations = _emptyLocations;
                    result            = resolvedVirtualPath;
                    ViewLocationCache.InsertViewLocation(controllerContext.HttpContext,
                                                         AppendDisplayModeToCacheKey(cacheKey, virtualPathDisplayInfo.DisplayMode.DisplayModeId), result);

                    if (controllerContext.DisplayMode == null)
                    {
                        controllerContext.DisplayMode = virtualPathDisplayInfo.DisplayMode;
                    }

                    // Populate the cache with the existing paths returned by all display modes.
                    // Since we currently don't keep track of cache misses, if we cache view.aspx on a request from a standard browser
                    // we don't want a cache hit for view.aspx from a mobile browser so we populate the cache with view.Mobile.aspx.
                    IEnumerable <IDisplayMode> allDisplayModes = DisplayModeProvider.Modes;
                    foreach (var displayMode in allDisplayModes)
                    {
                        if (displayMode.DisplayModeId != virtualPathDisplayInfo.DisplayMode.DisplayModeId)
                        {
                            var displayInfoToCache = displayMode.GetDisplayInfo(controllerContext.HttpContext,
                                                                                virtualPath, path => FileExists(controllerContext, path));

                            if (displayInfoToCache != null && displayInfoToCache.FilePath != null)
                            {
                                ViewLocationCache.InsertViewLocation(controllerContext.HttpContext,
                                                                     AppendDisplayModeToCacheKey(cacheKey, displayInfoToCache.DisplayMode.DisplayModeId),
                                                                     displayInfoToCache.FilePath);
                            }
                        }
                    }
                    break;
                }

                searchedLocations[i] = virtualPath;
            }

            return(result);
        }
        private string GetPath(ControllerContext controllerContext, string[] locations, string[] areaLocations, string[] moduleLocations, string[] moduleAreaLocations, string locationsPropertyName, string name, string controllerName, string cacheKeyPrefix, bool useCache, out string[] searchedLocations)
        {
            searchedLocations = g_emptyLocations;

            if (String.IsNullOrEmpty(name))
            {
                return(String.Empty);
            }

            string moduleName   = AreaHelpers.GetModuleName(controllerContext.RouteData);
            string areaName     = AreaHelpers.GetAreaName(controllerContext.RouteData);
            bool   usingModules = !string.IsNullOrEmpty(moduleName);
            bool   usingAreas   = !String.IsNullOrEmpty(areaName);
            List <ViewLocation> viewLocations = GetViewLocations(
                locations,
                usingModules || !usingAreas ? null : areaLocations,
                !usingModules ? null : moduleLocations,
                !usingModules || !usingAreas ? null : moduleAreaLocations);

            if (viewLocations.Count == 0)
            {
                throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture,
                                                                  "The property '{0}' cannot be null or empty.", locationsPropertyName));
            }

            bool   nameRepresentsPath = IsSpecificPath(name);
            string cacheKey           = this.CreateCacheKey(cacheKeyPrefix, name, (nameRepresentsPath) ? String.Empty : controllerName, areaName, moduleName);

            if (useCache)
            {
                // Only look at cached display modes that can handle the context.
                string cachedLocation = null;
                IEnumerable <IDisplayMode> possibleDisplayModes = DisplayModeProvider.GetAvailableDisplayModesForContext(controllerContext.HttpContext, controllerContext.DisplayMode);
                foreach (IDisplayMode displayMode in possibleDisplayModes)
                {
                    cachedLocation = ViewLocationCache.GetViewLocation(controllerContext.HttpContext, this.AppendDisplayModeToCacheKey(cacheKey, displayMode.DisplayModeId));

                    if (cachedLocation != null)
                    {
                        if (controllerContext.DisplayMode == null)
                        {
                            controllerContext.DisplayMode = displayMode;
                        }
                        break;
                    }
                }

                // if cachedLocation is null GetPath will be called again without using the cache.
                return(cachedLocation);
            }
            else
            {
                return((nameRepresentsPath) ?
                       this.GetPathFromSpecificName(controllerContext, name, cacheKey, ref searchedLocations) :
                       this.GetPathFromGeneralName(controllerContext, viewLocations, name, controllerName, areaName, moduleName, cacheKey, ref searchedLocations));
            }
        }
Example #17
0
        private string GetPath(ControllerContext controllerContext, string[] locations, string[] areaLocations,
                               string locationsPropertyName, string name, string controllerName, string cacheKeyPrefix, bool useCache,
                               out string[] searchedLocations)
        {
            searchedLocations = _emptyLocations;

            if (string.IsNullOrEmpty(name))
            {
                return(string.Empty);
            }

            var areaName      = AreaHelpers.GetAreaName(controllerContext.RouteData);
            var usingAreas    = !string.IsNullOrEmpty(areaName);
            var viewLocations = GetViewLocations(locations, usingAreas ? areaLocations : null);

            if (viewLocations.Count == 0)
            {
                throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture,
                                                                  HotcakesResources.Common_PropertyCannotBeNullOrEmpty, locationsPropertyName));
            }

            var nameRepresentsPath = IsSpecificPath(name);
            var rootFolder         = HotcakesApplication.Current.ViewsVirtualPath;
            var cacheKey           = CreateCacheKey(cacheKeyPrefix, name, nameRepresentsPath ? string.Empty : controllerName,
                                                    areaName, rootFolder);

            if (useCache)
            {
                // Only look at cached display modes that can handle the context.
                var possibleDisplayModes =
                    DisplayModeProvider.GetAvailableDisplayModesForContext(controllerContext.HttpContext,
                                                                           controllerContext.DisplayMode);
                foreach (var displayMode in possibleDisplayModes)
                {
                    var cachedLocation = ViewLocationCache.GetViewLocation(controllerContext.HttpContext,
                                                                           AppendDisplayModeToCacheKey(cacheKey, displayMode.DisplayModeId));

                    if (cachedLocation != null)
                    {
                        if (controllerContext.DisplayMode == null)
                        {
                            controllerContext.DisplayMode = displayMode;
                        }

                        return(cachedLocation);
                    }
                }

                // GetPath is called again without using the cache.
                return(null);
            }
            return(nameRepresentsPath
                ? GetPathFromSpecificName(controllerContext, name, rootFolder, cacheKey, ref searchedLocations)
                : GetPathFromGeneralName(controllerContext, viewLocations, name, controllerName, areaName, rootFolder,
                                         cacheKey, ref searchedLocations));
        }
Example #18
0
        internal static DisplayModeProvider AssignDisplayModeProvider(params WebPageRenderingBase[] pages)
        {
            var displayModeProvider = new DisplayModeProvider();

            foreach (var item in pages)
            {
                item.DisplayModeProvider = displayModeProvider;
            }
            return(displayModeProvider);
        }
Example #19
0
        public static void RegisterBasic(DisplayModeProvider instance)
        {
            instance.Modes.Clear();

            instance.Modes.Add(new DefaultDisplayMode("Preview")
            {
                ContextCondition = x => x.Request.Cookies.AllKeys.Contains("Preview")
            });

            instance.Modes.Add(new DefaultDisplayMode());
        }
        private string GetPath(ControllerContext controllerContext, string[] areaLocations, string[] sharedLocations, string name, string controllerName, string cacheKeyPrefix, bool useCache, out string[] searchedLocations)
        {
            searchedLocations = _emptyLocations;

            if (String.IsNullOrEmpty(name))
            {
                return(String.Empty);
            }

            var areaName = AreaHelpers.GetAreaName(controllerContext.RouteData);
            List <ViewLocation> viewLocations = GetViewLocations(sharedLocations, areaLocations);

            bool   nameRepresentsPath = IsSpecificPath(name);
            string cacheKey           = CreateCacheKey(cacheKeyPrefix, name, (nameRepresentsPath) ? String.Empty : controllerName, areaName);

            if (useCache)
            {
                // Only look at cached display modes that can handle the context.
                IEnumerable <IDisplayMode> possibleDisplayModes = DisplayModeProvider.GetAvailableDisplayModesForContext(controllerContext.HttpContext, controllerContext.DisplayMode);
                foreach (IDisplayMode displayMode in possibleDisplayModes)
                {
                    string cachedLocation = ViewLocationCache.GetViewLocation(controllerContext.HttpContext, AppendDisplayModeToCacheKey(cacheKey, displayMode.DisplayModeId));

                    if (cachedLocation == null)
                    {
                        // If any matching display mode location is not in the cache, fall back to the uncached behavior, which will repopulate all of our caches.
                        return(null);
                    }

                    // A non-empty cachedLocation indicates that we have a matching file on disk. Return that result.
                    if (cachedLocation.Length > 0)
                    {
                        if (controllerContext.DisplayMode == null)
                        {
                            controllerContext.DisplayMode = displayMode;
                        }

                        return(cachedLocation);
                    }
                    // An empty cachedLocation value indicates that we don't have a matching file on disk. Keep going down the list of possible display modes.
                }

                // GetPath is called again without using the cache.
                return(null);
            }
            else
            {
                return(nameRepresentsPath
                    ? GetPathFromSpecificName(controllerContext, name, cacheKey, ref searchedLocations)
                    : GetPathFromGeneralName(controllerContext, viewLocations, name, controllerName, areaName, cacheKey, ref searchedLocations));
            }
        }
Example #21
0
        public static void RegisterDisplayModes(DisplayModeProvider filters)
        {
            filters.Modes.Insert(
                0,
                new DefaultDisplayMode("WindowsPhone")
            {
                ContextCondition =
                    ctx =>
                {
                    var agent = ctx.Request.UserAgent ?? string.Empty;
                    agent     = agent.ToUpperInvariant();

                    return(agent.Contains("WINDOWS PHONE"));
                }
            });

            filters.Modes.Insert(
                1,
                new DefaultDisplayMode("Apple")
            {
                ContextCondition =
                    ctx =>
                {
                    var agent = ctx.Request.UserAgent ?? string.Empty;
                    agent     = agent.ToUpperInvariant();

                    return(agent.Contains("IPAD") ||
                           agent.Contains("IPOD") ||
                           agent.Contains("IPHONE") ||
                           agent.Contains("MACINTOSH"));
                }
            });

            filters.Modes.Insert(
                2,
                new DefaultDisplayMode("Android")
            {
                ContextCondition =
                    ctx =>
                {
                    var agent = ctx.Request.UserAgent ?? string.Empty;
                    agent     = agent.ToUpperInvariant();

                    return(agent.Contains("ANDROID"));
                }
            });
        }
        private string ResolveViewPath(string viewName, string areaName, string[] viewLocationFormats, string[] areaViewLocationFormats, List <string> viewLocationsSearched, ControllerContext controllerContext)
        {
            if (string.IsNullOrEmpty(viewName))
            {
                return(null);
            }

            var controllerName = controllerContext.RouteData.GetRequiredString("controller");

            if (IsSpecificPath(viewName))
            {
                var normalized = NormalizeViewName(viewName);

                viewLocationsSearched.Add(viewName);
                return(_views.ContainsKey(normalized) ? normalized : null);
            }

            areaViewLocationFormats = (areaName == null ? null : areaViewLocationFormats) ?? new string[0];
            viewLocationFormats     = viewLocationFormats ?? new string[0];

            var httpContext           = controllerContext.HttpContext;
            var availableDisplayModes = DisplayModeProvider.GetAvailableDisplayModesForContext(httpContext, controllerContext.DisplayMode);

            foreach (var displayMode in availableDisplayModes)
            {
                for (var i = 0; i < areaViewLocationFormats.Length; i++)
                {
                    var path = string.Format(areaViewLocationFormats[i], viewName, controllerName, areaName);
                    if (TryResolveView(httpContext, displayMode, ref path, viewLocationsSearched))
                    {
                        return(path);
                    }
                }

                for (var i = 0; i < viewLocationFormats.Length; i++)
                {
                    var path = string.Format(viewLocationFormats[i], viewName, controllerName);
                    if (TryResolveView(httpContext, displayMode, ref path, viewLocationsSearched))
                    {
                        return(path);
                    }
                }
            }

            return(null);
        }
Example #23
0
        /// <summary>
        /// Assigns a common object factory to the pages.
        /// </summary>
        internal static IVirtualPathFactory AssignObjectFactoriesAndDisplayModeProvider(params WebPageExecutingBase[] pages)
        {
            var objectFactory       = new HashVirtualPathFactory(pages);
            var displayModeProvider = new DisplayModeProvider();

            foreach (var item in pages)
            {
                item.VirtualPathFactory = objectFactory;
                var webPageRenderingBase = item as WebPageRenderingBase;
                if (webPageRenderingBase != null)
                {
                    webPageRenderingBase.DisplayModeProvider = displayModeProvider;
                }
            }

            return(objectFactory);
        }
Example #24
0
        public static void Register(DisplayModeProvider instance)
        {
            var categorizr = new Categorizr.Impl.Categorizr();

            instance.Modes.Insert(0, new DefaultDisplayMode("Mobile")
            {
                ContextCondition = c => categorizr.Detect(c.GetOverriddenUserAgent()).IsMobile
            });

            instance.Modes.Insert(1, new DefaultDisplayMode("Tablet")
            {
                ContextCondition = c => categorizr.Detect(c.GetOverriddenUserAgent()).IsTablet
            });

            instance.Modes.Insert(2, new DefaultDisplayMode("TV")
            {
                ContextCondition = c => categorizr.Detect(c.GetOverriddenUserAgent()).IsTv
            });
        }
Example #25
0
        private string GetPath(ControllerContext controllerContext, IEnumerable <string> locations, string[] areaLocations, string name, string controllerName, string cacheKeyPrefix, bool useCache, out IList <string> searchedLocations)
        {
            searchedLocations = new List <string>();

            if (string.IsNullOrEmpty(name))
            {
                return(string.Empty);
            }

            var areaName      = GetAreaName(controllerContext.RouteData);
            var usingAreas    = !string.IsNullOrEmpty(areaName);
            var viewLocations = GetViewLocations(locations, usingAreas ? areaLocations : null);

            var isSpecificPath = IsSpecificPath(name);
            var cacheKey       = CreateCacheKey(cacheKeyPrefix, name, isSpecificPath ? string.Empty : controllerName, areaName);

            // Check the cache using the first display mode, i.e. the most specific.

            var displayMode = DisplayModeProvider.GetAvailableDisplayModesForContext(controllerContext.HttpContext, controllerContext.DisplayMode).First();

            if (useCache)
            {
                // Look in the cache.

                var cachedLocation = ViewLocationCache.GetViewLocation(controllerContext.HttpContext, AppendDisplayModeToCacheKey(cacheKey, displayMode.DisplayModeId));
                if (cachedLocation != null)
                {
                    // The location has been found for this display mode meaning it has been resolved either way.

                    if (controllerContext.DisplayMode == null)
                    {
                        controllerContext.DisplayMode = displayMode;
                    }
                    return(cachedLocation == DoesNotExist ? string.Empty : cachedLocation);
                }
            }

            return(isSpecificPath
                ? GetPathFromSpecificName(controllerContext, name, cacheKey, out searchedLocations)
                : GetPathFromGeneralName(controllerContext, viewLocations, displayMode, name, controllerName, areaName, cacheKey, out searchedLocations));
        }
        // Helper to test smarty route match, null match string is used for no expected match
        private static void ConstraintTest(IEnumerable<string> validFiles, IEnumerable<string> supportedExt, string url, string match, string pathInfo, bool mobileDevice = false)
        {
            var objectFactory = new HashyBuildManager(validFiles);
            var mockContext = new Mock<HttpContextBase>();
            mockContext.Setup(context => context.Items).Returns(new Hashtable());
            mockContext.Setup(c => c.Request.Browser.IsMobileDevice).Returns(mobileDevice);
            mockContext.Setup(c => c.Request.Cookies).Returns(new HttpCookieCollection());
            mockContext.Setup(c => c.Response.Cookies).Returns(new HttpCookieCollection());
            var displayModeProvider = new DisplayModeProvider();

            WebPageMatch smartyMatch = WebPageRoute.MatchRequest(url, supportedExt, objectFactory, mockContext.Object, displayModeProvider);
            if (match != null)
            {
                Assert.NotNull(smartyMatch);
                Assert.Equal(match, smartyMatch.MatchedPath);
                Assert.Equal(pathInfo, smartyMatch.PathInfo);
            }
            else
            {
                Assert.Null(smartyMatch);
            }
        }
Example #27
0
        // Helper to test smarty route match, null match string is used for no expected match
        private static void ConstraintTest(
            IEnumerable <string> validFiles,
            IEnumerable <string> supportedExt,
            string url,
            string match,
            string pathInfo,
            bool mobileDevice = false
            )
        {
            var objectFactory = new HashyBuildManager(validFiles);
            var mockContext   = new Mock <HttpContextBase>();

            mockContext.Setup(context => context.Items).Returns(new Hashtable());
            mockContext.Setup(c => c.Request.Browser.IsMobileDevice).Returns(mobileDevice);
            mockContext.Setup(c => c.Request.Cookies).Returns(new HttpCookieCollection());
            mockContext.Setup(c => c.Response.Cookies).Returns(new HttpCookieCollection());
            var displayModeProvider = new DisplayModeProvider();

            WebPageMatch smartyMatch = WebPageRoute.MatchRequest(
                url,
                supportedExt.ToArray(),
                objectFactory.Exists,
                mockContext.Object,
                displayModeProvider
                );

            if (match != null)
            {
                Assert.NotNull(smartyMatch);
                Assert.Equal(match, smartyMatch.MatchedPath);
                Assert.Equal(pathInfo, smartyMatch.PathInfo);
            }
            else
            {
                Assert.Null(smartyMatch);
            }
        }
 /// <summary>
 /// Method returns display modes that are valid for current request context
 /// </summary>
 /// <param name="controllerContext">Current controller context</param>
 /// <returns>Valid display modes for current request ordered by their priority (e.g. ["Tablet", "Mobile", ""])</returns>
 private string[] GetAvailableDisplayModesForContext(ControllerContext controllerContext)
 {
     return(DisplayModeProvider.GetAvailableDisplayModesForContext(controllerContext.HttpContext, controllerContext.DisplayMode)
            .Select(mode => mode.DisplayModeId)
            .ToArray());
 }
 internal static DisplayModeProvider AssignDisplayModeProvider(params WebPageRenderingBase[] pages)
 {
     var displayModeProvider = new DisplayModeProvider();
     foreach (var item in pages)
     {
         item.DisplayModeProvider = displayModeProvider;
     }
     return displayModeProvider;
 }
        private string GetPath(ControllerContext controllerContext, string[] locations, string[] areaLocations, string locationsPropertyName, string name, string controllerName, string cacheKeyPrefix, bool useCache, out string[] searchedLocations)
        {
            searchedLocations = _emptyLocations;

            if (String.IsNullOrEmpty(name))
            {
                return(String.Empty);
            }

            string areaName = GetAreaName(controllerContext.RouteData);

            //little hack to get nop's admin area to be in /Administration/ instead of /Nop/Admin/ or Areas/Admin/
            if (!string.IsNullOrEmpty(areaName) && areaName.Equals("admin", StringComparison.InvariantCultureIgnoreCase))
            {
                var newLocations = areaLocations.ToList();
                newLocations.Insert(0, "~/Administration/Views/{1}/{0}.cshtml");
                newLocations.Insert(0, "~/Administration/Views/Shared/{0}.cshtml");
                areaLocations = newLocations.ToArray();
            }

            bool usingAreas = !String.IsNullOrEmpty(areaName);
            List <ViewLocation> viewLocations = GetViewLocations(locations, (usingAreas) ? areaLocations : null);

            if (viewLocations.Count == 0)
            {
                throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture,
                                                                  "", locationsPropertyName));
            }

            bool   nameRepresentsPath = IsSpecificPath(name);
            string cacheKey           = CreateCacheKey(cacheKeyPrefix, name, (nameRepresentsPath) ? String.Empty : controllerName, areaName);

            if (useCache)
            {
                // Only look at cached display modes that can handle the context.
                IEnumerable <IDisplayMode> possibleDisplayModes = DisplayModeProvider.GetAvailableDisplayModesForContext(controllerContext.HttpContext, controllerContext.DisplayMode);
                foreach (IDisplayMode displayMode in possibleDisplayModes)
                {
                    string cachedLocation = ViewLocationCache.GetViewLocation(controllerContext.HttpContext, AppendDisplayModeToCacheKey(cacheKey, displayMode.DisplayModeId));

                    if (cachedLocation == null)
                    {
                        // If any matching display mode location is not in the cache, fall back to the uncached behavior, which will repopulate all of our caches.
                        return(null);
                    }

                    // A non-empty cachedLocation indicates that we have a matching file on disk. Return that result.
                    if (cachedLocation.Length > 0)
                    {
                        if (controllerContext.DisplayMode == null)
                        {
                            controllerContext.DisplayMode = displayMode;
                        }

                        return(cachedLocation);
                    }
                    // An empty cachedLocation value indicates that we don't have a matching file on disk. Keep going down the list of possible display modes.
                }

                // GetPath is called again without using the cache.
                return(null);
            }
            else
            {
                return(nameRepresentsPath
                    ? GetPathFromSpecificName(controllerContext, name, cacheKey, ref searchedLocations)
                    : GetPathFromGeneralName(controllerContext, viewLocations, name, controllerName, areaName, cacheKey, ref searchedLocations));
            }
        }
        /// <summary>
        /// Assigns a common object factory to the pages.
        /// </summary>
        internal static IVirtualPathFactory AssignObjectFactoriesAndDisplayModeProvider(params WebPageExecutingBase[] pages)
        {
            var objectFactory = new HashVirtualPathFactory(pages);
            var displayModeProvider = new DisplayModeProvider();
            foreach (var item in pages)
            {
                item.VirtualPathFactory = objectFactory;
                var webPageRenderingBase = item as WebPageRenderingBase;
                if (webPageRenderingBase != null)
                {
                    webPageRenderingBase.DisplayModeProvider = displayModeProvider;
                }
            }

            return objectFactory;
        }
        public void GetDisplayModesForRequestReturnsNullIfNoDisplayModesHandleRequest()
        {
            // Arrange
            Mock<HttpContextBase> httpContext = new Mock<HttpContextBase>(MockBehavior.Strict);
            var displayModeProvider = new DisplayModeProvider();
            displayModeProvider.Modes.Clear();
            var displayMode1 = new Mock<IDisplayMode>(MockBehavior.Strict);
            displayMode1.Setup(d => d.CanHandleContext(It.IsAny<HttpContextBase>())).Returns(false);
            displayModeProvider.Modes.Add(displayMode1.Object);

            var displayMode2 = new Mock<IDisplayMode>(MockBehavior.Strict);
            displayMode2.Setup(d => d.CanHandleContext(It.IsAny<HttpContextBase>())).Returns(false);
            displayModeProvider.Modes.Add(displayMode2.Object);

            var displayMode3 = new Mock<IDisplayMode>(MockBehavior.Strict);
            displayMode3.Setup(d => d.CanHandleContext(It.IsAny<HttpContextBase>())).Returns(false);
            displayModeProvider.Modes.Add(displayMode3.Object);

            // Act
            DisplayInfo displayModeForRequest = displayModeProvider.GetDisplayInfoForVirtualPath("path", httpContext.Object, path => false, currentDisplayMode: null);

            // Assert
            Assert.Null(displayModeForRequest);
        }
Example #33
0
        protected virtual string ResolveViewPath(
            ControllerContext controllerContext,
            string areaName,
            string[] locations,
            string[] areaLocations,
            string locationsPropertyName,
            string name,
            string controllerName,
            string theme,
            string cacheKeyPrefix,
            bool useCache,
            out string[] searchedLocations)
        {
            searchedLocations = _emptyLocations;

            if (String.IsNullOrEmpty(name))
            {
                return(String.Empty);
            }

            bool usingAreas = !String.IsNullOrEmpty(areaName);

            if (usingAreas)
            {
                var isAdminArea = areaName.IsCaseInsensitiveEqual("admin");

                // "ExtraAreaViewLocations" gets injected by AdminThemedAttribute
                var extraAreaViewLocations = controllerContext.RouteData.DataTokens["ExtraAreaViewLocations"] as string[];

                if (extraAreaViewLocations != null && extraAreaViewLocations.Length > 0)
                {
                    var newLocations = areaLocations.ToList();
                    var viewType     = cacheKeyPrefix == "Partial"
                                                ? ViewType.Partial
                                                : ViewType.Layout;

                    if (isAdminArea)
                    {
                        // the admin area cannot fallback to itself. Prepend to list.
                        ExpandLocationFormats(extraAreaViewLocations, viewType).Reverse().Each(x => newLocations.Insert(0, x));
                    }
                    else
                    {
                        newLocations.AddRange(ExpandLocationFormats(extraAreaViewLocations, viewType));
                    }

                    areaLocations = newLocations.ToArray();
                }
            }

            var viewLocations = GetViewLocations(locations, (usingAreas) ? areaLocations : null);

            if (viewLocations.Count == 0)
            {
                throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, "Properties cannot be null or empty.", new object[] { locationsPropertyName }));
            }

            bool   nameRepresentsPath = IsSpecificPath(name);
            string cacheKey           = CreateCacheKey(cacheKeyPrefix, name, (nameRepresentsPath) ? String.Empty : controllerName, areaName, theme);

            if (useCache)
            {
                // Only look at cached display modes that can handle the context.
                var possibleDisplayModes = DisplayModeProvider.GetAvailableDisplayModesForContext(controllerContext.HttpContext, controllerContext.DisplayMode);
                foreach (var displayMode in possibleDisplayModes)
                {
                    string cachedLocation = ViewLocationCache.GetViewLocation(controllerContext.HttpContext, AppendDisplayModeToCacheKey(cacheKey, displayMode.DisplayModeId));

                    if (cachedLocation == null)
                    {
                        // If any matching display mode location is not in the cache, fall back to the uncached behavior, which will repopulate all of our caches.
                        return(null);
                    }

                    // A non-empty cachedLocation indicates that we have a matching file on disk. Return that result.
                    if (cachedLocation.Length > 0)
                    {
                        if (controllerContext.DisplayMode == null)
                        {
                            controllerContext.DisplayMode = displayMode;
                        }

                        return(cachedLocation);
                    }
                    // An empty cachedLocation value indicates that we don't have a matching file on disk. Keep going down the list of possible display modes.
                }

                // ResolveViewPath is called again without using the cache.
                return(null);
            }
            else
            {
                return(nameRepresentsPath
                                        ? GetPathFromSpecificName(controllerContext, name, cacheKey, ref searchedLocations)
                                        : GetPathFromGeneralName(controllerContext, viewLocations, name, controllerName, areaName, theme, cacheKey, ref searchedLocations));
            }
        }
        public void MatchRequestDoesNotSetDisplayModeIfNoMatch()
        {
            // Arrange
            var objectFactory = new HashyBuildManager(new string[] { "~/page.Mobile.aspx" });
            var mockContext = new Mock<HttpContextBase>();
            mockContext.Setup(context => context.Items).Returns(new Hashtable());
            mockContext.Setup(c => c.Request.Browser.IsMobileDevice).Returns(true);
            mockContext.Setup(c => c.Request.Cookies).Returns(new HttpCookieCollection());
            mockContext.Setup(c => c.Response.Cookies).Returns(new HttpCookieCollection());

            var displayModeProvider = new DisplayModeProvider();
            var displayMode = new Mock<IDisplayMode>(MockBehavior.Strict);
            displayMode.Setup(d => d.CanHandleContext(mockContext.Object)).Returns(false);
            displayModeProvider.Modes.Add(displayMode.Object);

            // Act
            WebPageMatch smartyMatch = WebPageRoute.MatchRequest("notThere.aspx", new string[] { "aspx" }, objectFactory, mockContext.Object, displayModeProvider);

            // Assert
            Assert.Null(DisplayModeProvider.GetDisplayMode(mockContext.Object));
        }
        public void GetAvailableDisplayModesReturnsOnlyModesThatCanHandleContext()
        {
            // Arrange
            Mock<HttpContextBase> httpContext = new Mock<HttpContextBase>(MockBehavior.Strict);
            var displayModeProvider = new DisplayModeProvider();
            displayModeProvider.Modes.Clear();
            var displayMode1 = new Mock<IDisplayMode>(MockBehavior.Strict);
            displayMode1.Setup(d => d.CanHandleContext(It.IsAny<HttpContextBase>())).Returns(false);
            displayModeProvider.Modes.Add(displayMode1.Object);

            var displayMode2 = new Mock<IDisplayMode>(MockBehavior.Strict);
            displayMode2.Setup(d => d.CanHandleContext(It.IsAny<HttpContextBase>())).Returns(true);
            displayModeProvider.Modes.Add(displayMode2.Object);

            var displayMode3 = new Mock<IDisplayMode>(MockBehavior.Strict);
            displayMode3.Setup(d => d.CanHandleContext(It.IsAny<HttpContextBase>())).Returns(false);
            displayModeProvider.Modes.Add(displayMode3.Object);

            // Act
            var availableDisplayModes = displayModeProvider.GetAvailableDisplayModesForContext(httpContext.Object, displayMode1.Object, requireConsistentDisplayMode: false).ToList();

            // Assert
            Assert.Equal(1, availableDisplayModes.Count);
            Assert.Equal(displayMode2.Object, availableDisplayModes[0]);
        }
        public void MatchRequestSetsDisplayModeOfFirstMatchPerContext()
        {
            // Arrange
            var objectFactory = new HashyBuildManager(new string[] { "~/page.Mobile.aspx", "~/nonMobile.aspx" });
            var mockContext = new Mock<HttpContextBase>();
            mockContext.Setup(context => context.Items).Returns(new Hashtable());
            mockContext.Setup(c => c.Request.Browser.IsMobileDevice).Returns(true);
            mockContext.Setup(c => c.Request.Cookies).Returns(new HttpCookieCollection());
            mockContext.Setup(c => c.Response.Cookies).Returns(new HttpCookieCollection());

            var displayModeProvider = new DisplayModeProvider();

            // Act
            WebPageMatch mobileMatch = WebPageRoute.MatchRequest("page.aspx", new string[] { "aspx" }, objectFactory, mockContext.Object, displayModeProvider);

            // Assert
            Assert.NotNull(mobileMatch.MatchedPath);
            Assert.Equal(DisplayModeProvider.MobileDisplayModeId, DisplayModeProvider.GetDisplayMode(mockContext.Object).DisplayModeId);
        }
        protected override string GetPathFromGeneralName(
            ControllerContext controllerContext,
            List <ViewLocation> locations,
            string name,
            string controllerName,
            string areaName,
            string theme,
            string cacheKey,
            ref string[] searchedLocations)
        {
            var parentThemes = LoadParentThemes(theme);

            string result           = string.Empty;
            var    checkedLocations = new List <string>();

            for (int i = 0; i < locations.Count; i++)
            {
                var    location               = locations[i];
                string virtualPath            = location.Format(name, controllerName, areaName, theme);
                var    virtualPathDisplayInfo = DisplayModeProvider.GetDisplayInfoForVirtualPath(
                    virtualPath,
                    controllerContext.HttpContext,
                    path => FileExists(controllerContext, path),
                    controllerContext.DisplayMode);

                if (virtualPathDisplayInfo == null && virtualPath.IndexOf("/Themes/", StringComparison.InvariantCultureIgnoreCase) > -1)
                {
                    // We're checking themes location. Try parent themes as well.

                    foreach (var parentTheme in parentThemes)
                    {
                        // 1. Track the last checked location
                        checkedLocations.Add(virtualPath);

                        // 2. Try parent theme
                        virtualPath            = location.Format(name, controllerName, areaName, parentTheme);
                        virtualPathDisplayInfo = DisplayModeProvider.GetDisplayInfoForVirtualPath(
                            virtualPath,
                            controllerContext.HttpContext,
                            path => FileExists(controllerContext, path),
                            controllerContext.DisplayMode);

                        if (virtualPathDisplayInfo != null)
                        {
                            // 3. We found target view in the parent theme
                            break;
                        }
                    }
                }

                if (virtualPathDisplayInfo != null)
                {
                    string resolvedVirtualPath = virtualPathDisplayInfo.FilePath;

                    checkedLocations.Clear();
                    result = resolvedVirtualPath;
                    ViewLocationCache.InsertViewLocation(
                        controllerContext.HttpContext,
                        AppendDisplayModeToCacheKey(cacheKey, virtualPathDisplayInfo.DisplayMode.DisplayModeId), result);

                    if (controllerContext.DisplayMode == null)
                    {
                        controllerContext.DisplayMode = virtualPathDisplayInfo.DisplayMode;
                    }

                    var allDisplayModes = DisplayModeProvider.Modes;
                    foreach (IDisplayMode displayMode in allDisplayModes)
                    {
                        if (displayMode.DisplayModeId != virtualPathDisplayInfo.DisplayMode.DisplayModeId)
                        {
                            var displayInfoToCache = displayMode.GetDisplayInfo(controllerContext.HttpContext, virtualPath, virtualPathExists: path => FileExists(controllerContext, path));

                            string cacheValue = string.Empty;
                            if (displayInfoToCache != null && displayInfoToCache.FilePath != null)
                            {
                                cacheValue = displayInfoToCache.FilePath;
                            }

                            ViewLocationCache.InsertViewLocation(
                                controllerContext.HttpContext,
                                AppendDisplayModeToCacheKey(cacheKey, displayMode.DisplayModeId), cacheValue);
                        }
                    }

                    break;
                }

                checkedLocations.Add(virtualPath);
            }

            searchedLocations = checkedLocations.ToArray();
            return(result);
        }
        public static void Register(DisplayModeProvider instance)
        {
            //instance.Modes.Add(new DefaultDisplayMode("Mobile-Dark-Preview")
            //{
            //    ContextCondition = x => IsMobile(x) && CurrentTheme(x) == "dark" && IsPreview(x)
            //});

            //instance.Modes.Add(new DefaultDisplayMode("Tablet-Dark-Preview")
            //{
            //    ContextCondition = x => IsTablet(x) && CurrentTheme(x) == "dark" && IsPreview(x)
            //});

            //instance.Modes.Add(new DefaultDisplayMode("Mobile-Dark")
            //{
            //    ContextCondition = x => IsMobile(x) && CurrentTheme(x) == "dark"
            //});

            //instance.Modes.Add(new DefaultDisplayMode("Tablet-Dark")
            //{
            //    ContextCondition = x => IsTablet(x) && CurrentTheme(x) == "dark"
            //});

            //instance.Modes.Add(new DefaultDisplayMode("Dark-Preview")
            //{
            //    ContextCondition = x => CurrentTheme(x) == "dark" && IsPreview(x)
            //});

            //instance.Modes.Add(new DefaultDisplayMode("Mobile-Preview")
            //{
            //    ContextCondition = x => IsMobile(x) && IsPreview(x)
            //});

            //instance.Modes.Add(new DefaultDisplayMode("Tablet-Preview")
            //{
            //    ContextCondition = x => IsTablet(x) && IsPreview(x)
            //});

            //instance.Modes.Add(new DefaultDisplayMode("Mobile")
            //{
            //    ContextCondition = x => IsMobile(x)
            //});

            //instance.Modes.Add(new DefaultDisplayMode("Tablet")
            //{
            //    ContextCondition = x => IsTablet(x)
            //});

            //instance.Modes.Add(new DefaultDisplayMode("Dark")
            //{
            //    ContextCondition = x => CurrentTheme(x) == "dark"
            //});

            //instance.Modes.Add(new DefaultDisplayMode("Preview")
            //{
            //    ContextCondition = x => IsPreview(x)
            //});


            var builder = new DisplayModeMatrixBuilder();

            var matrix = builder
                         //.Precondition(x => false)
                         //.SetEvaluateBehavior(EvaluateBehavior.Lazy)
                         .AddOptionalFactor("Device", l => l
                                            .Evidence("Tablet", x => IsTablet(x))
                                            .Evidence("Mobile", x => IsMobile(x)))
                         .AddOptionalFactor("Theme", l => l
                                            .Evidence("Dark", x => CurrentTheme(x) == "dark")
                                            .Evidence("Light", x => CurrentTheme(x) == "light"))
                         .AddOptionalFactor("Preview", l => l
                                            .Evidence("Preview", x => IsPreview(x)))
                         .Build();

            instance.Modes.Clear();

            foreach (var profile in matrix)
            {
                instance.Modes.Add(new DefaultDisplayMode(profile.Name)
                {
                    ContextCondition = profile.ContextCondition
                });
            }

            instance.Modes.Add(new DefaultDisplayMode(""));
        }
Example #39
0
        public static void RegisterHarder(DisplayModeProvider instance)
        {
            Func <HttpContextBase, bool>   IsMobile     = x => x.GetOverriddenBrowser().IsMobileDevice;
            Func <HttpContextBase, bool>   IsTablet     = x => Regex.IsMatch(x.GetOverriddenUserAgent(), "iPad|Tablet", RegexOptions.IgnoreCase);
            Func <HttpContextBase, string> CurrentTheme = x => x.Request.Cookies.AllKeys.Contains("Theme") ? x.Request.Cookies["Theme"].Value : string.Empty;
            Func <HttpContextBase, bool>   IsPreview    = x => x.Request.Cookies.AllKeys.Contains("Preview");

            instance.Modes.Clear();

            instance.Modes.Add(new DefaultDisplayMode("Tablet-Dark-Preview")
            {
                ContextCondition = x => IsTablet(x) && CurrentTheme(x) == "dark" && IsPreview(x)
            });

            instance.Modes.Add(new DefaultDisplayMode("Mobile-Dark-Preview")
            {
                ContextCondition = x => IsMobile(x) && CurrentTheme(x) == "dark" && IsPreview(x)
            });

            instance.Modes.Add(new DefaultDisplayMode("Tablet-Dark")
            {
                ContextCondition = x => IsTablet(x) && CurrentTheme(x) == "dark"
            });

            instance.Modes.Add(new DefaultDisplayMode("Mobile-Dark")
            {
                ContextCondition = x => IsMobile(x) && CurrentTheme(x) == "dark"
            });

            instance.Modes.Add(new DefaultDisplayMode("Dark-Preview")
            {
                ContextCondition = x => CurrentTheme(x) == "dark" && IsPreview(x)
            });

            instance.Modes.Add(new DefaultDisplayMode("Tablet-Preview")
            {
                ContextCondition = x => IsTablet(x) && IsPreview(x)
            });

            instance.Modes.Add(new DefaultDisplayMode("Mobile-Preview")
            {
                ContextCondition = x => IsMobile(x) && IsPreview(x)
            });

            instance.Modes.Add(new DefaultDisplayMode("Tablet")
            {
                ContextCondition = x => IsTablet(x)
            });

            instance.Modes.Add(new DefaultDisplayMode("Mobile")
            {
                ContextCondition = x => IsMobile(x)
            });

            instance.Modes.Add(new DefaultDisplayMode("Dark")
            {
                ContextCondition = x => CurrentTheme(x) == "dark"
            });

            instance.Modes.Add(new DefaultDisplayMode("Preview")
            {
                ContextCondition = x => IsPreview(x)
            });

            instance.Modes.Add(new DefaultDisplayMode());
        }