// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information. using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Web.WebPages.Administration.PackageManager; using System.Xml.Linq; using Moq; using NuGet; using Xunit; namespace System.Web.WebPages.Administration.Test { public class WebProjectSystemTest { [Fact] public void ResolvePathReturnsAppCodePathIfPathIsSourceFile() { // Arrange var path = "Foo.cs"; var webProjectSystem = new WebProjectSystem(@"x:\"); // Act var resolvedPath = webProjectSystem.ResolvePath(path); // Assert Assert.Equal(@"App_Code\Foo.cs", resolvedPath); } [Fact] public void ResolvePathReturnsOriginalPathIfSourceFilePathIsAlreadyUnderAppCode() { // Arrange var path = @"App_Code\Foo.cs"; var webProjectSystem = new WebProjectSystem(@"x:\"); // Act var resolvedPath = webProjectSystem.ResolvePath(path); // Assert Assert.Equal(path, resolvedPath); } [Fact] public void ResolvePathReturnsOriginalPathIfFileIsNotSource() { // Arrange var path = @"Foo.js"; var webProjectSystem = new WebProjectSystem(@"x:\"); // Act var resolvedPath = webProjectSystem.ResolvePath(path); // Assert Assert.Equal(path, resolvedPath); } [Fact] public void AddPackageWithFrameworkReferenceCreatesWebConfigIfItDoesNotExist() { // Arrange string webConfigPath = @"x:\my-website\web.config"; MemoryStream memoryStream = new MemoryStream(); var fileSystem = new Mock(); fileSystem.SetupGet(f => f.Root).Returns("x:\\my-website"); fileSystem.Setup(f => f.FileExists(It.Is(p => p.Equals(webConfigPath)))).Returns(false).Verifiable(); fileSystem.Setup(f => f.AddFile(It.Is(p => p.Equals(webConfigPath)), It.IsAny())) .Callback((_, s) => { s.CopyTo(memoryStream); }); var references = "System"; // Act WebProjectSystem.AddReferencesToConfig(fileSystem.Object, references); // Assert memoryStream.Seek(0, SeekOrigin.Begin); XDocument document = XDocument.Load(memoryStream); var element = document.Root; Assert.Equal(element.Name, "configuration"); // Use SingleOrDefault to ensure there's exactly one element with that name var assemblies = document.Root .Elements().SingleOrDefault(e => e.Name.ToString().Equals("system.web")) .Elements().SingleOrDefault(e => e.Name.ToString().Equals("compilation")) .Elements().SingleOrDefault(e => e.Name.ToString().Equals("assemblies")); Assert.Equal(references, assemblies.Elements().First().Attribute("assembly").Value); } [Fact] public void AddPackageWithFrameworkReferenceCreatesWebConfigIfItExistsWithoutAssembliesNode() { // Arrange var webConfigPath = @"x:\my-website\web.config"; var webConfigContent = @" ".AsStream(); MemoryStream memoryStream = new MemoryStream(); var fileSystem = new Mock(); fileSystem.SetupGet(f => f.Root).Returns("x:\\my-website"); fileSystem.Setup(f => f.FileExists(It.Is(p => p.Equals(webConfigPath)))).Returns(true).Verifiable(); fileSystem.Setup(f => f.OpenFile(It.Is(p => p.Equals(webConfigPath)))).Returns(webConfigContent); fileSystem.Setup(f => f.AddFile(It.Is(p => p.Equals(webConfigPath)), It.IsAny())) .Callback((_, s) => { s.CopyTo(memoryStream); }); var references = "System.Data"; // Act WebProjectSystem.AddReferencesToConfig(fileSystem.Object, references); // Assert memoryStream.Seek(0, SeekOrigin.Begin); XDocument document = XDocument.Load(memoryStream); var element = document.Root; Assert.Equal(element.Name, "configuration"); // Use SingleOrDefault to ensure there's exactly one element with that name var assemblies = document.Root .Elements().SingleOrDefault(e => e.Name.ToString().Equals("system.web")) .Elements().SingleOrDefault(e => e.Name.ToString().Equals("compilation")) .Elements().SingleOrDefault(e => e.Name.ToString().Equals("assemblies")); Assert.Equal(references, assemblies.Elements().First().Attribute("assembly").Value); // Make sure the original web.config content is unaffected Assert.Equal("test", document.Root .Elements().SingleOrDefault(e => e.Name.ToString().Equals("connectionStrings")) .Elements().SingleOrDefault(e => e.Name.ToString().Equals("add")) .Attributes().SingleOrDefault(e => e.Name.ToString().Equals("name")).Value); Assert.Equal("awesomeprofile", document.Root.Element("system.web").Element("profiles").Element("add").Attribute("name").Value); } [Fact] public void AddPackageWithFrameworkReferenceDoesNotAffectWebConfigIfReferencesAlreadyExist() { // Arrange var webConfigPath = @"x:\my-website\web.config"; var memoryStream = new NeverCloseMemoryStream(@" "); var fileSystem = new Mock(); fileSystem.SetupGet(f => f.Root).Returns("x:\\my-website"); fileSystem.Setup(f => f.FileExists(It.Is(p => p.Equals(webConfigPath)))).Returns(true); fileSystem.Setup(f => f.OpenFile(It.Is(p => p.Equals(webConfigPath)))).Returns(() => { memoryStream.Seek(0, SeekOrigin.Begin); return memoryStream; }); fileSystem.Setup(f => f.AddFile(It.Is(p => p.Equals(webConfigPath)), It.IsAny())) .Callback((_, stream) => { memoryStream = new NeverCloseMemoryStream(stream.ReadToEnd()); }); // Act WebProjectSystem.AddReferencesToConfig(fileSystem.Object, "System.Data"); WebProjectSystem.AddReferencesToConfig(fileSystem.Object, "Microsoft.Abstractions"); // Assert memoryStream.Seek(0, SeekOrigin.Begin); XDocument document = XDocument.Load(memoryStream); var element = document.Root; Assert.Equal(element.Name, "configuration"); // Use SingleOrDefault to ensure there's exactly one element with that name var assemblies = document.Root .Elements().SingleOrDefault(e => e.Name.ToString().Equals("system.web")) .Elements().SingleOrDefault(e => e.Name.ToString().Equals("compilation")) .Elements().SingleOrDefault(e => e.Name.ToString().Equals("assemblies")); Assert.Equal(2, assemblies.Elements("add").Count()); Assert.Equal("System.Data, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35", assemblies.Elements().First().Attribute("assembly").Value); Assert.Equal("Microsoft.Abstractions", assemblies.Elements().Last().Attribute("assembly").Value); // Make sure the original web.config content is unaffected Assert.Equal("test", document.Root .Elements().SingleOrDefault(e => e.Name.ToString().Equals("connectionStrings")) .Elements().SingleOrDefault(e => e.Name.ToString().Equals("add")) .Attributes().SingleOrDefault(e => e.Name.ToString().Equals("name")).Value); Assert.Equal("awesomeprofile", document.Root.Element("system.web").Element("profiles").Element("add").Attribute("name").Value); } [Fact] public void ResolveAssemblyPartialNameForCommonAssemblies() { // Arrange var commonAssemblies = new Dictionary(StringComparer.OrdinalIgnoreCase) { { "System.Data", "System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" }, { "System.Data.Linq", "System.Data.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" }, { "System.Net", "System.Net, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" }, { "System.Runtime.Caching", "System.Runtime.Caching, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" }, { "System.Xml", "System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" }, { "System.Web.DynamicData", "System.Web.DynamicData, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" }, }; // Act and Assert foreach (var item in commonAssemblies) { var resolvedName = WebProjectSystem.ResolvePartialAssemblyName(item.Key); Assert.Equal(item.Value, resolvedName); } } private static IFileSystem GetFileSystem() { var fileSystem = new Mock(); fileSystem.Setup(c => c.Root).Returns(@"X:\packages\"); return fileSystem.Object; } private class NeverCloseMemoryStream : MemoryStream { public NeverCloseMemoryStream(string content) : base(Encoding.UTF8.GetBytes(content)) { } protected override void Dispose(bool disposing) { // Do nothing } } } }