diff --git a/src/Orchard.Core.Tests/Indexing/DefaultIndexProviderTests.cs b/src/Orchard.Core.Tests/Indexing/DefaultIndexProviderTests.cs index 0862af8ed..7b2501149 100644 --- a/src/Orchard.Core.Tests/Indexing/DefaultIndexProviderTests.cs +++ b/src/Orchard.Core.Tests/Indexing/DefaultIndexProviderTests.cs @@ -11,6 +11,7 @@ using Orchard.Indexing; using Orchard.Core.Indexing.Lucene; using Orchard.Services; using Orchard.Tests.Environment.Configuration; +using Orchard.Tests.FileSystems.AppData; namespace Orchard.Tests.Indexing { public class DefaultIndexProviderTests { diff --git a/src/Orchard.Core.Tests/Indexing/DefaultSearchBuilderTests.cs b/src/Orchard.Core.Tests/Indexing/DefaultSearchBuilderTests.cs index 5d9b9fa10..b4f2d5c37 100644 --- a/src/Orchard.Core.Tests/Indexing/DefaultSearchBuilderTests.cs +++ b/src/Orchard.Core.Tests/Indexing/DefaultSearchBuilderTests.cs @@ -11,6 +11,7 @@ using Orchard.Indexing; using Orchard.Core.Indexing.Lucene; using Orchard.Services; using Orchard.Tests.Environment.Configuration; +using Orchard.Tests.FileSystems.AppData; namespace Orchard.Tests.Indexing { public class DefaultSearchBuilderTests { diff --git a/src/Orchard.Tests/Environment/Blueprint/DefaultShellDescriptorCacheTests.cs b/src/Orchard.Tests/Environment/Blueprint/DefaultShellDescriptorCacheTests.cs index c03e50ad1..85fdc63f3 100644 --- a/src/Orchard.Tests/Environment/Blueprint/DefaultShellDescriptorCacheTests.cs +++ b/src/Orchard.Tests/Environment/Blueprint/DefaultShellDescriptorCacheTests.cs @@ -9,6 +9,7 @@ using Orchard.FileSystems.AppData; using Orchard.FileSystems.VirtualPath; using Orchard.Services; using Orchard.Tests.Environment.Configuration; +using Orchard.Tests.FileSystems.AppData; namespace Orchard.Tests.Environment.Blueprint { [TestFixture] diff --git a/src/Orchard.Tests/Environment/Configuration/DefaultTenantManagerTests.cs b/src/Orchard.Tests/Environment/Configuration/DefaultTenantManagerTests.cs index 07e9ddcc9..cd09c493f 100644 --- a/src/Orchard.Tests/Environment/Configuration/DefaultTenantManagerTests.cs +++ b/src/Orchard.Tests/Environment/Configuration/DefaultTenantManagerTests.cs @@ -7,6 +7,7 @@ using Orchard.Environment.Configuration; using Orchard.FileSystems.AppData; using Orchard.FileSystems.VirtualPath; using Orchard.Services; +using Orchard.Tests.FileSystems.AppData; namespace Orchard.Tests.Environment.Configuration { [TestFixture] diff --git a/src/Orchard.Tests/Environment/DefaultOrchardHostTests.cs b/src/Orchard.Tests/Environment/DefaultOrchardHostTests.cs index 5114b5685..0e58c1783 100644 --- a/src/Orchard.Tests/Environment/DefaultOrchardHostTests.cs +++ b/src/Orchard.Tests/Environment/DefaultOrchardHostTests.cs @@ -25,6 +25,7 @@ using Orchard.Mvc.ModelBinders; using Orchard.Mvc.Routes; using Orchard.Tests.Environment.Configuration; using Orchard.Tests.Environment.TestDependencies; +using Orchard.Tests.FileSystems.AppData; using Orchard.Tests.Stubs; using Orchard.Tests.Utility; diff --git a/src/Orchard.Tests/Environment/Extensions/ExtensionLoaderCoordinatorTests.cs b/src/Orchard.Tests/Environment/Extensions/ExtensionLoaderCoordinatorTests.cs new file mode 100644 index 000000000..f468ef868 --- /dev/null +++ b/src/Orchard.Tests/Environment/Extensions/ExtensionLoaderCoordinatorTests.cs @@ -0,0 +1,361 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Autofac; +using NUnit.Framework; +using Orchard.Environment.Extensions; +using Orchard.Environment.Extensions.Folders; +using Orchard.Environment.Extensions.Loaders; +using Orchard.Environment.Extensions.Models; +using Orchard.Tests.Extensions.ExtensionTypes; + +namespace Orchard.Tests.Environment.Extensions { + [TestFixture] + public class ExtensionLoaderCoordinatorTests { + private IContainer _container; + private IExtensionManager _manager; + private IExtensionLoaderCoordinator _loader; + private StubFolders _folders; + + [SetUp] + public void Init() { + var builder = new ContainerBuilder(); + _folders = new StubFolders(); + builder.RegisterInstance(_folders).As(); + builder.RegisterType().As(); + _container = builder.Build(); + _manager = _container.Resolve(); + } + + public class StubFolders : IExtensionFolders { + public StubFolders() { + Manifests = new Dictionary(); + } + + public IDictionary Manifests { get; set; } + + public IEnumerable AvailableExtensions() { + foreach (var e in Manifests) { + string name = e.Key; + var parseResult = ExtensionFolders.ParseManifest(Manifests[name]); + yield return ExtensionFolders.GetDescriptorForExtension("~/", name, "Module", parseResult); + } + } + } + + public class StubLoaders : ExtensionLoaderBase { + #region Implementation of IExtensionLoader + + public override int Order { + get { return 1; } + } + + public override ExtensionProbeEntry Probe(ExtensionDescriptor descriptor) { + return new ExtensionProbeEntry { Descriptor = descriptor, Loader = this }; + } + + public override ExtensionEntry Load(ExtensionDescriptor descriptor) { + return new ExtensionEntry { Descriptor = descriptor, ExportedTypes = new[] { typeof(Alpha), typeof(Beta), typeof(Phi) } }; + } + + #endregion + } + + + [Test] + public void AvailableExtensionsShouldFollowCatalogLocations() { + _folders.Manifests.Add("foo", "name: Foo"); + _folders.Manifests.Add("bar", "name: Bar"); + _folders.Manifests.Add("frap", "name: Frap"); + _folders.Manifests.Add("quad", "name: Quad"); + + var available = _manager.AvailableExtensions(); + + Assert.That(available.Count(), Is.EqualTo(4)); + Assert.That(available, Has.Some.Property("Name").EqualTo("foo")); + } + + [Test] + public void ExtensionDescriptorsShouldHaveNameAndVersion() { + + _folders.Manifests.Add("Sample", @" +name: Sample Extension +version: 2.x +"); + + var descriptor = _manager.AvailableExtensions().Single(); + Assert.That(descriptor.Name, Is.EqualTo("Sample")); + Assert.That(descriptor.DisplayName, Is.EqualTo("Sample Extension")); + Assert.That(descriptor.Version, Is.EqualTo("2.x")); + } + + [Test] + public void ExtensionDescriptorsShouldBeParsedForMinimalModuleTxt() { + + _folders.Manifests.Add("SuperWiki", @" +name: SuperWiki +version: 1.0.3 +orchardversion: 1 +features: + SuperWiki: + Description: My super wiki module for Orchard. +"); + + var descriptor = _manager.AvailableExtensions().Single(); + Assert.That(descriptor.Name, Is.EqualTo("SuperWiki")); + Assert.That(descriptor.Version, Is.EqualTo("1.0.3")); + Assert.That(descriptor.OrchardVersion, Is.EqualTo("1")); + Assert.That(descriptor.Features.Count(), Is.EqualTo(1)); + Assert.That(descriptor.Features.First().Name, Is.EqualTo("SuperWiki")); + Assert.That(descriptor.Features.First().Extension.Name, Is.EqualTo("SuperWiki")); + Assert.That(descriptor.Features.First().Description, Is.EqualTo("My super wiki module for Orchard.")); + } + + [Test] + public void ExtensionDescriptorsShouldBeParsedForCompleteModuleTxt() { + + _folders.Manifests.Add("MyCompany.AnotherWiki", @" +name: AnotherWiki +author: Coder Notaprogrammer +website: http://anotherwiki.codeplex.com +version: 1.2.3 +orchardversion: 1 +features: + AnotherWiki: + Description: My super wiki module for Orchard. + Dependencies: Versioning, Search + Category: Content types + AnotherWiki Editor: + Description: A rich editor for wiki contents. + Dependencies: TinyMCE, AnotherWiki + Category: Input methods + AnotherWiki DistributionList: + Description: Sends e-mail alerts when wiki contents gets published. + Dependencies: AnotherWiki, Email Subscriptions + Category: Email + AnotherWiki Captcha: + Description: Kills spam. Or makes it zombie-like. + Dependencies: AnotherWiki, reCaptcha + Category: Spam +"); + + var descriptor = _manager.AvailableExtensions().Single(); + Assert.That(descriptor.Name, Is.EqualTo("MyCompany.AnotherWiki")); + Assert.That(descriptor.DisplayName, Is.EqualTo("AnotherWiki")); + Assert.That(descriptor.Author, Is.EqualTo("Coder Notaprogrammer")); + Assert.That(descriptor.WebSite, Is.EqualTo("http://anotherwiki.codeplex.com")); + Assert.That(descriptor.Version, Is.EqualTo("1.2.3")); + Assert.That(descriptor.OrchardVersion, Is.EqualTo("1")); + Assert.That(descriptor.Features.Count(), Is.EqualTo(5)); + foreach (var featureDescriptor in descriptor.Features) { + switch (featureDescriptor.Name) { + case "AnotherWiki": + Assert.That(featureDescriptor.Extension, Is.SameAs(descriptor)); + Assert.That(featureDescriptor.Description, Is.EqualTo("My super wiki module for Orchard.")); + Assert.That(featureDescriptor.Category, Is.EqualTo("Content types")); + Assert.That(featureDescriptor.Dependencies.Count(), Is.EqualTo(2)); + Assert.That(featureDescriptor.Dependencies.Contains("Versioning")); + Assert.That(featureDescriptor.Dependencies.Contains("Search")); + break; + case "AnotherWiki Editor": + Assert.That(featureDescriptor.Extension, Is.SameAs(descriptor)); + Assert.That(featureDescriptor.Description, Is.EqualTo("A rich editor for wiki contents.")); + Assert.That(featureDescriptor.Category, Is.EqualTo("Input methods")); + Assert.That(featureDescriptor.Dependencies.Count(), Is.EqualTo(2)); + Assert.That(featureDescriptor.Dependencies.Contains("TinyMCE")); + Assert.That(featureDescriptor.Dependencies.Contains("AnotherWiki")); + break; + case "AnotherWiki DistributionList": + Assert.That(featureDescriptor.Extension, Is.SameAs(descriptor)); + Assert.That(featureDescriptor.Description, Is.EqualTo("Sends e-mail alerts when wiki contents gets published.")); + Assert.That(featureDescriptor.Category, Is.EqualTo("Email")); + Assert.That(featureDescriptor.Dependencies.Count(), Is.EqualTo(2)); + Assert.That(featureDescriptor.Dependencies.Contains("AnotherWiki")); + Assert.That(featureDescriptor.Dependencies.Contains("Email Subscriptions")); + break; + case "AnotherWiki Captcha": + Assert.That(featureDescriptor.Extension, Is.SameAs(descriptor)); + Assert.That(featureDescriptor.Description, Is.EqualTo("Kills spam. Or makes it zombie-like.")); + Assert.That(featureDescriptor.Category, Is.EqualTo("Spam")); + Assert.That(featureDescriptor.Dependencies.Count(), Is.EqualTo(2)); + Assert.That(featureDescriptor.Dependencies.Contains("AnotherWiki")); + Assert.That(featureDescriptor.Dependencies.Contains("reCaptcha")); + break; + // default feature. + case "MyCompany.AnotherWiki": + Assert.That(featureDescriptor.Extension, Is.SameAs(descriptor)); + break; + default: + Assert.Fail("Features not parsed correctly"); + break; + } + } + } + + [Test] + public void ExtensionManagerShouldLoadFeatures() { + var extensionLoader = new StubLoaders(); + var extensionFolder = new StubFolders(); + + extensionFolder.Manifests.Add("TestModule", @" +name: TestModule +version: 1.0.3 +orchardversion: 1 +features: + TestModule: + Description: My test module for Orchard. + TestFeature: + Description: Contains the Phi type. +"); + + IExtensionManager extensionManager = new ExtensionManager(new[] { extensionFolder }, new[] { extensionLoader }); + var testFeature = extensionManager.AvailableExtensions() + .SelectMany(x => x.Features); + + var features = extensionManager.LoadFeatures(testFeature); + var types = features.SelectMany(x => x.ExportedTypes); + + Assert.That(types.Count(), Is.Not.EqualTo(0)); + } + + [Test] + public void ExtensionManagerFeaturesContainNonAbstractClasses() { + var extensionLoader = new StubLoaders(); + var extensionFolder = new StubFolders(); + + extensionFolder.Manifests.Add("TestModule", @" +name: TestModule +version: 1.0.3 +orchardversion: 1 +features: + TestModule: + Description: My test module for Orchard. + TestFeature: + Description: Contains the Phi type. +"); + + IExtensionManager extensionManager = new ExtensionManager(new[] { extensionFolder }, new[] { extensionLoader }); + var testFeature = extensionManager.AvailableExtensions() + .SelectMany(x => x.Features); + + var features = extensionManager.LoadFeatures(testFeature); + var types = features.SelectMany(x => x.ExportedTypes); + + foreach (var type in types) { + Assert.That(type.IsClass); + Assert.That(!type.IsAbstract); + } + } + + [Test] + public void ExtensionManagerShouldThrowIfFeatureDoesNotExist() { + var featureDescriptor = new FeatureDescriptor { Name = "NoSuchFeature" }; + Assert.Throws(() => _manager.LoadFeatures(new[] { featureDescriptor })); + } + + [Test] + public void ExtensionManagerTestFeatureAttribute() { + var extensionLoader = new StubLoaders(); + var extensionFolder = new StubFolders(); + + extensionFolder.Manifests.Add("TestModule", @" +name: TestModule +version: 1.0.3 +orchardversion: 1 +features: + TestModule: + Description: My test module for Orchard. + TestFeature: + Description: Contains the Phi type. +"); + + IExtensionManager extensionManager = new ExtensionManager(new[] { extensionFolder }, new[] { extensionLoader }); + var testFeature = extensionManager.AvailableExtensions() + .SelectMany(x => x.Features) + .Single(x => x.Name == "TestFeature"); + + foreach (var feature in extensionManager.LoadFeatures(new[] { testFeature })) { + foreach (var type in feature.ExportedTypes) { + foreach (OrchardFeatureAttribute featureAttribute in type.GetCustomAttributes(typeof(OrchardFeatureAttribute), false)) { + Assert.That(featureAttribute.FeatureName, Is.EqualTo("TestFeature")); + } + } + } + } + + [Test] + public void ExtensionManagerLoadFeatureReturnsTypesFromSpecificFeaturesWithFeatureAttribute() { + var extensionLoader = new StubLoaders(); + var extensionFolder = new StubFolders(); + + extensionFolder.Manifests.Add("TestModule", @" +name: TestModule +version: 1.0.3 +orchardversion: 1 +features: + TestModule: + Description: My test module for Orchard. + TestFeature: + Description: Contains the Phi type. +"); + + IExtensionManager extensionManager = new ExtensionManager(new[] { extensionFolder }, new[] { extensionLoader }); + var testFeature = extensionManager.AvailableExtensions() + .SelectMany(x => x.Features) + .Single(x => x.Name == "TestFeature"); + + foreach (var feature in extensionManager.LoadFeatures(new[] { testFeature })) { + foreach (var type in feature.ExportedTypes) { + Assert.That(type == typeof(Phi)); + } + } + } + + [Test] + public void ExtensionManagerLoadFeatureDoesNotReturnTypesFromNonMatchingFeatures() { + var extensionLoader = new StubLoaders(); + var extensionFolder = new StubFolders(); + + extensionFolder.Manifests.Add("TestModule", @" +name: TestModule +version: 1.0.3 +orchardversion: 1 +features: + TestModule: + Description: My test module for Orchard. + TestFeature: + Description: Contains the Phi type. +"); + + IExtensionManager extensionManager = new ExtensionManager(new[] { extensionFolder }, new[] { extensionLoader }); + var testModule = extensionManager.AvailableExtensions() + .SelectMany(x => x.Features) + .Single(x => x.Name == "TestModule"); + + foreach (var feature in extensionManager.LoadFeatures(new[] { testModule })) { + foreach (var type in feature.ExportedTypes) { + Assert.That(type != typeof(Phi)); + Assert.That((type == typeof(Alpha) || (type == typeof(Beta)))); + } + } + } + + [Test] + public void ModuleNameIsIntroducedAsFeatureImplicitly() { + var extensionLoader = new StubLoaders(); + var extensionFolder = new StubFolders(); + + extensionFolder.Manifests.Add("Minimalistic", @" +name: Minimalistic +version: 1.0.3 +orchardversion: 1 +"); + + IExtensionManager extensionManager = new ExtensionManager(new[] { extensionFolder }, new[] { extensionLoader }); + var minimalisticModule = extensionManager.AvailableExtensions().Single(x => x.Name == "Minimalistic"); + + Assert.That(minimalisticModule.Features.Count(), Is.EqualTo(1)); + Assert.That(minimalisticModule.Features.Single().Name, Is.EqualTo("Minimalistic")); + } + } +} \ No newline at end of file diff --git a/src/Orchard.Tests/Environment/Extensions/ExtensionManagerTests.cs b/src/Orchard.Tests/Environment/Extensions/ExtensionManagerTests.cs index 5d0d2fcb9..978beb16a 100644 --- a/src/Orchard.Tests/Environment/Extensions/ExtensionManagerTests.cs +++ b/src/Orchard.Tests/Environment/Extensions/ExtensionManagerTests.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Linq; using Autofac; using NUnit.Framework; -using Orchard.Caching; using Orchard.Environment.Extensions; using Orchard.Environment.Extensions.Folders; using Orchard.Environment.Extensions.Loaders; diff --git a/src/Orchard.Tests/Environment/Configuration/AppDataFolderTests.cs b/src/Orchard.Tests/FileSystems/AppData/AppDataFolderTests.cs similarity index 92% rename from src/Orchard.Tests/Environment/Configuration/AppDataFolderTests.cs rename to src/Orchard.Tests/FileSystems/AppData/AppDataFolderTests.cs index d82cc188d..62f24377f 100644 --- a/src/Orchard.Tests/Environment/Configuration/AppDataFolderTests.cs +++ b/src/Orchard.Tests/FileSystems/AppData/AppDataFolderTests.cs @@ -2,10 +2,9 @@ using System.Linq; using NUnit.Framework; using Orchard.FileSystems.AppData; -using Orchard.FileSystems.VirtualPath; -using Orchard.Services; +using Orchard.Tests.Stubs; -namespace Orchard.Tests.Environment.Configuration { +namespace Orchard.Tests.FileSystems.AppData { [TestFixture] public class AppDataFolderTests { private string _tempFolder; @@ -18,7 +17,8 @@ namespace Orchard.Tests.Environment.Configuration { public static IAppDataFolder CreateAppDataFolder(string tempFolder) { var folderRoot = new StubAppDataFolderRoot {RootPath = "~/App_Data", RootFolder = tempFolder}; - return new AppDataFolder(folderRoot, new DefaultVirtualPathMonitor(new Clock())); + var monitor = new StubVirtualPathMonitor(); + return new AppDataFolder(folderRoot, monitor); } [SetUp] diff --git a/src/Orchard.Tests/FileSystems/Dependencies/DependenciesFolderTests.cs b/src/Orchard.Tests/FileSystems/Dependencies/DependenciesFolderTests.cs new file mode 100644 index 000000000..c1baec0f5 --- /dev/null +++ b/src/Orchard.Tests/FileSystems/Dependencies/DependenciesFolderTests.cs @@ -0,0 +1,49 @@ +using System.IO; +using NUnit.Framework; +using Orchard.FileSystems.AppData; +using Orchard.FileSystems.Dependencies; +using Orchard.Tests.FileSystems.AppData; + +namespace Orchard.Tests.FileSystems.Dependencies { + [TestFixture] + public class DependenciesFolderTests { + private string _tempFolder; + private IAppDataFolder _appDataFolder; + private IDependenciesFolder _dependenciesFolder; + + [SetUp] + public void Init() { + _tempFolder = Path.GetTempFileName(); + File.Delete(_tempFolder); + + _appDataFolder = AppDataFolderTests.CreateAppDataFolder(_tempFolder); + _dependenciesFolder = new DefaultDependenciesFolder(new Stubs.StubCacheManager(), _appDataFolder); + } + + [TearDown] + public void Term() { + Directory.Delete(_tempFolder, true); + } + + [Test] + public void LoadDescriptorsShouldReturnEmptyList() { + Directory.Delete(_tempFolder, true); + var e = _dependenciesFolder.LoadDescriptors(); + Assert.That(e, Is.Empty); + } + + [Test] + public void StoreDescriptors() { + Directory.Delete(_tempFolder, true); + var d = new DependencyDescriptor { + LoaderName = "test", + Name = "name", + VirtualPath = "~/bin" + }; + + _dependenciesFolder.StoreDescriptors(new [] { d }); + var e = _dependenciesFolder.LoadDescriptors(); + Assert.That(e, Has.Count.EqualTo(1)); + } + } +} diff --git a/src/Orchard.Tests/Orchard.Framework.Tests.csproj b/src/Orchard.Tests/Orchard.Framework.Tests.csproj index 2204f2df9..289908bc1 100644 --- a/src/Orchard.Tests/Orchard.Framework.Tests.csproj +++ b/src/Orchard.Tests/Orchard.Framework.Tests.csproj @@ -185,10 +185,11 @@ + - + @@ -196,9 +197,11 @@ + + @@ -270,6 +273,7 @@ true +