/test/Microsoft.Web.Helpers.Test/ThemesTest.cs
C# | 372 lines | 249 code | 66 blank | 57 comment | 0 complexity | 14fbee72b16a09fb214aa9ce637ebcc8 MD5 | raw file
- using System;
- using System.Collections.Generic;
- using System.Web.Hosting;
- using System.Web.WebPages.Scope;
- using Moq;
- using Xunit;
- using Assert = Microsoft.TestCommon.AssertEx;
- namespace Microsoft.Web.Helpers.Test
- {
- public class ThemesTest
- {
- [Fact]
- public void Initialize_WithBadParams_Throws()
- {
- // Arrange
- var mockVpp = new Mock<VirtualPathProvider>().Object;
- var scope = new ScopeStorageDictionary();
- // Act and Assert
- Assert.ThrowsArgumentNullOrEmptyString(() => new ThemesImplementation(mockVpp, scope).Initialize(null, "foo"), "themeDirectory");
- Assert.ThrowsArgumentNullOrEmptyString(() => new ThemesImplementation(mockVpp, scope).Initialize("", "foo"), "themeDirectory");
- Assert.ThrowsArgumentNullOrEmptyString(() => new ThemesImplementation(mockVpp, scope).Initialize("~/folder", null), "defaultTheme");
- Assert.ThrowsArgumentNullOrEmptyString(() => new ThemesImplementation(mockVpp, scope).Initialize("~/folder", ""), "defaultTheme");
- }
- [Fact]
- public void CurrentThemeThrowsIfAssignedNullOrEmpty()
- {
- // Arrange
- var mockVpp = new Mock<VirtualPathProvider>().Object;
- var scope = new ScopeStorageDictionary();
- var themesImpl = new ThemesImplementation(mockVpp, scope);
- // Act and Assert
- Assert.ThrowsArgumentNullOrEmptyString(() => { themesImpl.CurrentTheme = null; }, "value");
- Assert.ThrowsArgumentNullOrEmptyString(() => { themesImpl.CurrentTheme = String.Empty; }, "value");
- }
- [Fact]
- public void InvokingPropertiesAndMethodsBeforeInitializationThrows()
- {
- // Arrange
- var mockVpp = new Mock<VirtualPathProvider>().Object;
- var scope = new ScopeStorageDictionary();
- var themesImpl = new ThemesImplementation(mockVpp, scope);
- // Act and Assert
- Assert.Throws<InvalidOperationException>(() => themesImpl.CurrentTheme = "Foo",
- @"You must call the ""Themes.Initialize"" method before you call any other method of the ""Themes"" class.");
- Assert.Throws<InvalidOperationException>(() => { var x = themesImpl.CurrentTheme; },
- @"You must call the ""Themes.Initialize"" method before you call any other method of the ""Themes"" class.");
- Assert.Throws<InvalidOperationException>(() => { var x = themesImpl.AvailableThemes; },
- @"You must call the ""Themes.Initialize"" method before you call any other method of the ""Themes"" class.");
- Assert.Throws<InvalidOperationException>(() => { var x = themesImpl.DefaultTheme; },
- @"You must call the ""Themes.Initialize"" method before you call any other method of the ""Themes"" class.");
- Assert.Throws<InvalidOperationException>(() => { var x = themesImpl.GetResourcePath("baz"); },
- @"You must call the ""Themes.Initialize"" method before you call any other method of the ""Themes"" class.");
- Assert.Throws<InvalidOperationException>(() => { var x = themesImpl.GetResourcePath("baz", "some-file"); },
- @"You must call the ""Themes.Initialize"" method before you call any other method of the ""Themes"" class.");
- }
- [Fact]
- public void InitializeThrowsIfDefaultThemeDirectoryDoesNotExist()
- {
- // Arrange
- var defaultTheme = "default-theme";
- var themeDirectory = "theme-directory";
- var scope = new ScopeStorageDictionary();
- var themesImpl = new ThemesImplementation(GetVirtualPathProvider(themeDirectory, new Dir("not-default-theme")), scope);
- // Act And Assert
- Assert.ThrowsArgument(
- () => themesImpl.Initialize(themeDirectory: themeDirectory, defaultTheme: defaultTheme),
- "defaultTheme",
- "Unknown theme 'default-theme'. Ensure that a directory labeled 'default-theme' exists under the theme directory.");
- }
- [Fact]
- public void ThemesImplUsesScopeStorageToStoreProperties()
- {
- // Arrange
- var defaultTheme = "default-theme";
- var themeDirectory = "theme-directory";
- var scope = new ScopeStorageDictionary();
- var themesImpl = new ThemesImplementation(GetVirtualPathProvider(themeDirectory, new Dir(defaultTheme)), scope);
- // Act
- themesImpl.Initialize(themeDirectory: themeDirectory, defaultTheme: defaultTheme);
- // Ensure Theme use scope storage to store properties
- Assert.Equal(scope[ThemesImplementation.ThemesInitializedKey], true);
- Assert.Equal(scope[ThemesImplementation.ThemeDirectoryKey], themeDirectory);
- Assert.Equal(scope[ThemesImplementation.DefaultThemeKey], defaultTheme);
- }
- [Fact]
- public void ThemesImplUsesDefaultThemeWhenNoCurrentThemeIsSpecified()
- {
- // Arrange
- var defaultTheme = "default-theme";
- var themeDirectory = "theme-directory";
- var scope = new ScopeStorageDictionary();
- var themesImpl = new ThemesImplementation(GetVirtualPathProvider(themeDirectory, new Dir(defaultTheme)), scope);
- themesImpl.Initialize(themeDirectory, defaultTheme);
- // Act and Assert
- // CurrentTheme falls back to default theme when null
- Assert.Equal(themesImpl.CurrentTheme, defaultTheme);
- }
- [Fact]
- public void ThemesImplThrowsIfCurrentThemeIsInvalid()
- {
- // Arrange
- var defaultTheme = "default-theme";
- var themeDirectory = "theme-directory";
- var themesImpl = new ThemesImplementation(GetVirtualPathProvider(themeDirectory, new Dir(defaultTheme), new Dir("not-a-random-value")), new ScopeStorageDictionary());
- themesImpl.Initialize(themeDirectory, defaultTheme);
- // Act and Assert
- Assert.ThrowsArgument(() => themesImpl.CurrentTheme = "random-value",
- "value",
- "Unknown theme 'random-value'. Ensure that a directory labeled 'random-value' exists under the theme directory.");
- }
- [Fact]
- public void ThemesImplUsesScopeStorageToStoreCurrentTheme()
- {
- // Arrange
- var defaultTheme = "default-theme";
- var themeDirectory = "theme-directory";
- var currentThemeDir = "custom-theme-dir";
- var scope = new ScopeStorageDictionary();
- var themesImpl = new ThemesImplementation(GetVirtualPathProvider(themeDirectory, new Dir(defaultTheme), new Dir("custom-theme-dir")), scope);
- // Act
- themesImpl.Initialize(themeDirectory, defaultTheme);
- themesImpl.CurrentTheme = currentThemeDir;
- // Assert
- Assert.Equal(scope[ThemesImplementation.CurrentThemeKey], currentThemeDir);
- }
- [Fact]
- public void GetResourcePathThrowsIfCurrentDirectoryIsNull()
- {
- // Arrange
- var themesImpl = new ThemesImplementation(scopeStorage: new ScopeStorageDictionary(),
- vpp: GetVirtualPathProvider("themes", new Dir("default"), new Dir("mobile"), new Dir(@"mobile", "wp7.css")));
- themesImpl.Initialize("themes", "default");
- // Act and Assert
- Assert.ThrowsArgumentNull(() => themesImpl.GetResourcePath(folder: null, fileName: "wp7.css"), "folder");
- }
- [Fact]
- public void GetResourcePathThrowsIfFileNameIsNullOrEmpty()
- {
- // Arrange
- var themesImpl = new ThemesImplementation(scopeStorage: new ScopeStorageDictionary(),
- vpp: GetVirtualPathProvider("themes", new Dir("default"), new Dir("mobile"), new Dir(@"mobile", "wp7.css")));
- themesImpl.Initialize("themes", "default");
- // Act and Assert
- Assert.ThrowsArgumentNullOrEmptyString(() => themesImpl.GetResourcePath(folder: String.Empty, fileName: null), "fileName");
- Assert.ThrowsArgumentNullOrEmptyString(() => themesImpl.GetResourcePath(folder: String.Empty, fileName: String.Empty), "fileName");
- }
- [Fact]
- public void GetResourcePathReturnsItemFromThemeRootIfAvailable()
- {
- // Arrange
- var themesImpl = new ThemesImplementation(scopeStorage: new ScopeStorageDictionary(),
- vpp: GetVirtualPathProvider("themes", new Dir("default"), new Dir("mobile"), new Dir(@"mobile", "wp7.css")));
- themesImpl.Initialize("themes", "default");
- // Act
- themesImpl.CurrentTheme = "mobile";
- var themePath = themesImpl.GetResourcePath(fileName: "wp7.css");
- // Assert
- Assert.Equal(themePath, @"themes/mobile/wp7.css");
- }
- [Fact]
- public void GetResourcePathReturnsItemFromCurrentThemeDirectoryIfAvailable()
- {
- // Arrange
- var themesImpl = new ThemesImplementation(scopeStorage: new ScopeStorageDictionary(),
- vpp: GetVirtualPathProvider("themes", new Dir("default"), new Dir("mobile"), new Dir(@"mobile\styles", "wp7.css"), new Dir(@"default\styles", "main.css")));
- themesImpl.Initialize("themes", "default");
- // Act
- themesImpl.CurrentTheme = "mobile";
- var themePath = themesImpl.GetResourcePath(folder: "styles", fileName: "wp7.css");
- // Assert
- Assert.Equal(themePath, @"themes/mobile/styles/wp7.css");
- }
- [Fact]
- public void GetResourcePathReturnsItemFromDefaultThemeDirectoryIfNotFoundInCurrentThemeDirectory()
- {
- // Arrange
- var themesImpl = new ThemesImplementation(scopeStorage: new ScopeStorageDictionary(),
- vpp: GetVirtualPathProvider("themes", new Dir("default"), new Dir("mobile"), new Dir(@"mobile\styles", "wp7.css"), new Dir(@"default\styles", "main.css")));
- themesImpl.Initialize("themes", "default");
- // Act
- themesImpl.CurrentTheme = "mobile";
- var themePath = themesImpl.GetResourcePath(folder: "styles", fileName: "main.css");
- // Assert
- Assert.Equal(themePath, @"themes/default/styles/main.css");
- }
- [Fact]
- public void GetResourcePathReturnsNullIfDirectoryDoesNotExist()
- {
- // Arrange
- var themesImpl = new ThemesImplementation(scopeStorage: new ScopeStorageDictionary(),
- vpp: GetVirtualPathProvider("themes", new Dir("default"), new Dir("mobile"), new Dir(@"mobile\styles", "wp7.css"), new Dir(@"default\styles", "main.css")));
- themesImpl.Initialize("themes", "default");
- // Act
- themesImpl.CurrentTheme = "mobile";
- var themePath = themesImpl.GetResourcePath(folder: "does-not-exist", fileName: "main.css");
- // Assert
- Assert.Null(themePath);
- }
- [Fact]
- public void GetResourcePathReturnsNullIfItemNotFoundInCurrentAndDefaultThemeDirectories()
- {
- // Arrange
- var themesImpl = new ThemesImplementation(scopeStorage: new ScopeStorageDictionary(),
- vpp: GetVirtualPathProvider("themes", new Dir("default"), new Dir("mobile"), new Dir(@"mobile\styles", "wp7.css"), new Dir(@"default\styles", "main.css")));
- themesImpl.Initialize("themes", "default");
- // Act
- themesImpl.CurrentTheme = "mobile";
- var themePath = themesImpl.GetResourcePath(folder: "styles", fileName: "awesome-blinking-text.css");
- // Assert
- Assert.Null(themePath);
- }
- [Fact]
- public void AvaliableThemesReturnsTopLevelDirectoriesUnderThemeDirectory()
- {
- // Arrange
- var themesImpl = new ThemesImplementation(scopeStorage: new ScopeStorageDictionary(),
- vpp: GetVirtualPathProvider("themes", new Dir("default"), new Dir("mobile"), new Dir("rotary-phone")));
- // Act
- themesImpl.Initialize("themes", "default");
- var themes = themesImpl.AvailableThemes;
- // Assert
- Assert.Equal(3, themes.Count);
- Assert.Equal(themes[0], "default");
- Assert.Equal(themes[1], "mobile");
- Assert.Equal(themes[2], "rotary-phone");
- }
- /// <remarks>
- /// // folder structure:
- /// // /root
- /// // /foo
- /// // /bar.cs
- /// // testing that a file specified as foo/bar in folder root will return null
- /// </remarks>
- [Fact]
- public void FileWithSlash_ReturnsNull()
- {
- // Arrange
- var themesImpl = new ThemesImplementation(scopeStorage: new ScopeStorageDictionary(),
- vpp: GetVirtualPathProvider("themes", new Dir("default"), new Dir("root"), new Dir(@"root\foo", "wp7.css"), new Dir(@"default\styles", "main.css")));
- // Act
- var actual = themesImpl.FindMatchingFile("root", "foo/bar.cs");
- // Assert
- Assert.Null(actual);
- }
- [Fact]
- public void DirectoryWithNoFilesReturnsNull()
- {
- // Arrange
- var themesImpl = new ThemesImplementation(scopeStorage: new ScopeStorageDictionary(),
- vpp: GetVirtualPathProvider("themes", new Dir("default"), new Dir("empty-dir")));
- // Act
- var actual = themesImpl.FindMatchingFile(@"themes\empty-dir", "main.css");
- // Assert
- Assert.Null(actual);
- }
- [Fact]
- public void MatchingFiles_ReturnsCorrectFile()
- {
- // Arrange
- var themesImpl = new ThemesImplementation(scopeStorage: new ScopeStorageDictionary(),
- vpp: GetVirtualPathProvider("themes", new Dir(@"nomatchingfiles", "foo.cs")));
- // Act
- var bar = themesImpl.FindMatchingFile(@"themes\nomatchingfiles", "bar.cs");
- var foo = themesImpl.FindMatchingFile(@"themes\nomatchingfiles", "foo.cs");
- // Assert
- Assert.Null(bar);
- Assert.Equal(@"themes/nomatchingfiles/foo.cs", foo);
- }
- private static VirtualPathProvider GetVirtualPathProvider(string themeRoot, params Dir[] fileSystem)
- {
- var mockVpp = new Mock<VirtualPathProvider>();
- var dirRoot = new Mock<VirtualDirectory>(themeRoot);
- var themeDirectories = new List<VirtualDirectory>();
- foreach (var directory in fileSystem)
- {
- var dir = new Mock<VirtualDirectory>(directory.Name);
- var directoryPath = themeRoot + '\\' + directory.Name;
- dir.SetupGet(d => d.Name).Returns(directory.Name);
- mockVpp.Setup(c => c.GetDirectory(It.Is<string>(p => p.Equals(directoryPath, StringComparison.OrdinalIgnoreCase)))).Returns(dir.Object);
- var fileList = new List<VirtualFile>();
- foreach (var item in directory.Files)
- {
- var filePath = directoryPath + '\\' + item;
- var file = new Mock<VirtualFile>(filePath);
- file.SetupGet(f => f.Name).Returns(item);
- fileList.Add(file.Object);
- }
- dir.SetupGet(c => c.Files).Returns(fileList);
- themeDirectories.Add(dir.Object);
- }
- dirRoot.SetupGet(c => c.Directories).Returns(themeDirectories);
- mockVpp.Setup(c => c.GetDirectory(themeRoot)).Returns(dirRoot.Object);
- return mockVpp.Object;
- }
- private class Dir
- {
- public Dir(string name, params string[] files)
- {
- Name = name;
- Files = files;
- }
- public string Name { get; private set; }
- public IEnumerable<string> Files { get; private set; }
- }
- }
- }