From 4eb92e63ec042bd0c202b35457dfce58bb3c054f Mon Sep 17 00:00:00 2001 From: Suha Can Date: Mon, 26 Apr 2010 16:21:06 -0700 Subject: [PATCH 1/5] - IExtensionManager refactoring: LoadFeature is obsoleted and internal in favor of LoadFeatures. - Related changes to callers. --HG-- branch : dev --- .../Environment/DefaultOrchardHostTests.cs | 4 ---- .../Extensions/ExtensionManagerTests.cs | 16 ++++++++++------ .../StandardExtensionRouteProviderTests.cs | 9 --------- .../Environment/Extensions/ExtensionManager.cs | 2 +- .../Environment/Extensions/IExtensionManager.cs | 1 - 5 files changed, 11 insertions(+), 21 deletions(-) diff --git a/src/Orchard.Tests/Environment/DefaultOrchardHostTests.cs b/src/Orchard.Tests/Environment/DefaultOrchardHostTests.cs index 44d183c15..f85ed9f31 100644 --- a/src/Orchard.Tests/Environment/DefaultOrchardHostTests.cs +++ b/src/Orchard.Tests/Environment/DefaultOrchardHostTests.cs @@ -105,10 +105,6 @@ namespace Orchard.Tests.Environment { } } - public Feature LoadFeature(FeatureDescriptor featureDescriptor) { - throw new NotImplementedException(); - } - public IEnumerable ActiveExtensions_Obsolete() { throw new NotImplementedException(); } diff --git a/src/Orchard.Tests/Environment/Extensions/ExtensionManagerTests.cs b/src/Orchard.Tests/Environment/Extensions/ExtensionManagerTests.cs index bdfdc8356..0e5026b09 100644 --- a/src/Orchard.Tests/Environment/Extensions/ExtensionManagerTests.cs +++ b/src/Orchard.Tests/Environment/Extensions/ExtensionManagerTests.cs @@ -256,7 +256,7 @@ features: [Test] public void ExtensionManagerShouldThrowIfFeatureDoesNotExist() { var featureDescriptor = new FeatureDescriptor { Name = "NoSuchFeature" }; - Assert.Throws(() => _manager.LoadFeature(featureDescriptor)); + Assert.Throws(() => _manager.LoadFeatures(new [] { featureDescriptor })); } [Test] @@ -302,8 +302,10 @@ features: .SelectMany(x => x.Features) .Single(x => x.Name == "TestFeature"); - foreach (var type in extensionManager.LoadFeature(testFeature).ExportedTypes) { - Assert.That(type == typeof(Phi)); + foreach (var feature in extensionManager.LoadFeatures(new[] { testFeature })) { + foreach (var type in feature.ExportedTypes) { + Assert.That(type == typeof(Phi)); + } } } @@ -328,9 +330,11 @@ features: .SelectMany(x => x.Features) .Single(x => x.Name == "TestModule"); - foreach (var type in extensionManager.LoadFeature(testModule).ExportedTypes) { - Assert.That(type != typeof(Phi)); - Assert.That((type == typeof(Alpha) || (type == typeof(Beta)))); + 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)))); + } } } diff --git a/src/Orchard.Tests/Mvc/Routes/StandardExtensionRouteProviderTests.cs b/src/Orchard.Tests/Mvc/Routes/StandardExtensionRouteProviderTests.cs index bb67e703b..b272e06e6 100644 --- a/src/Orchard.Tests/Mvc/Routes/StandardExtensionRouteProviderTests.cs +++ b/src/Orchard.Tests/Mvc/Routes/StandardExtensionRouteProviderTests.cs @@ -68,10 +68,6 @@ namespace Orchard.Tests.Mvc.Routes { throw new NotImplementedException(); } - public Feature LoadFeature(FeatureDescriptor featureDescriptor) { - throw new NotImplementedException(); - } - public IEnumerable ActiveExtensions_Obsolete() { yield return new ExtensionEntry { Descriptor = new ExtensionDescriptor { @@ -87,11 +83,6 @@ namespace Orchard.Tests.Mvc.Routes { }; } - public Feature LoadFeature(string featureName) { - throw new NotImplementedException(); - } - - public void InstallExtension(string extensionType, HttpPostedFileBase extensionBundle) { throw new NotImplementedException(); } diff --git a/src/Orchard/Environment/Extensions/ExtensionManager.cs b/src/Orchard/Environment/Extensions/ExtensionManager.cs index 697116307..fdf3edeaa 100644 --- a/src/Orchard/Environment/Extensions/ExtensionManager.cs +++ b/src/Orchard/Environment/Extensions/ExtensionManager.cs @@ -119,7 +119,7 @@ namespace Orchard.Environment.Extensions { return featureDescriptors; } - public Feature LoadFeature(FeatureDescriptor featureDescriptor) { + private Feature LoadFeature(FeatureDescriptor featureDescriptor) { var featureName = featureDescriptor.Name; string extensionName = GetExtensionForFeature(featureName); if (extensionName == null) throw new ArgumentException(T("Feature ") + featureName + T(" was not found in any of the installed extensions")); diff --git a/src/Orchard/Environment/Extensions/IExtensionManager.cs b/src/Orchard/Environment/Extensions/IExtensionManager.cs index feb59ebc1..e982c69d6 100644 --- a/src/Orchard/Environment/Extensions/IExtensionManager.cs +++ b/src/Orchard/Environment/Extensions/IExtensionManager.cs @@ -6,7 +6,6 @@ namespace Orchard.Environment.Extensions { public interface IExtensionManager { IEnumerable AvailableExtensions(); IEnumerable LoadFeatures(IEnumerable featureDescriptors); - Feature LoadFeature(FeatureDescriptor featureDescriptor); IEnumerable ActiveExtensions_Obsolete(); void InstallExtension(string extensionType, HttpPostedFileBase extensionBundle); From 9819dfa8b133423ca31fe33199de9bef5f4880ef Mon Sep 17 00:00:00 2001 From: Suha Can Date: Mon, 26 Apr 2010 16:52:31 -0700 Subject: [PATCH 2/5] - Some more refactoring, IExtensionManager.AvailableExtensions should be used instead of the obsoleted ActiveExtensions method to query extensions in the system. - ActiveExtensions will be removed once the HackInstallationGenerator is removed. --HG-- branch : dev --- src/Orchard/Environment/Extensions/IExtensionManager.cs | 5 +++-- src/Orchard/Mvc/ViewEngines/ViewEngineFilter.cs | 6 +++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/Orchard/Environment/Extensions/IExtensionManager.cs b/src/Orchard/Environment/Extensions/IExtensionManager.cs index e982c69d6..9100056e2 100644 --- a/src/Orchard/Environment/Extensions/IExtensionManager.cs +++ b/src/Orchard/Environment/Extensions/IExtensionManager.cs @@ -6,9 +6,10 @@ namespace Orchard.Environment.Extensions { public interface IExtensionManager { IEnumerable AvailableExtensions(); IEnumerable LoadFeatures(IEnumerable featureDescriptors); - - IEnumerable ActiveExtensions_Obsolete(); void InstallExtension(string extensionType, HttpPostedFileBase extensionBundle); void UninstallExtension(string extensionType, string extensionName); + + // Used by the HackInstallationGenerator and will be removed along with it. + IEnumerable ActiveExtensions_Obsolete(); } } \ No newline at end of file diff --git a/src/Orchard/Mvc/ViewEngines/ViewEngineFilter.cs b/src/Orchard/Mvc/ViewEngines/ViewEngineFilter.cs index d7ba7a38a..a2345afaa 100644 --- a/src/Orchard/Mvc/ViewEngines/ViewEngineFilter.cs +++ b/src/Orchard/Mvc/ViewEngines/ViewEngineFilter.cs @@ -52,10 +52,10 @@ namespace Orchard.Mvc.ViewEngines { } - var modules = _extensionManager.ActiveExtensions_Obsolete() - .Where(x => x.Descriptor.ExtensionType == "Module"); + var modules = _extensionManager.AvailableExtensions() + .Where(x => x.ExtensionType == "Module"); - var moduleLocations = modules.Select(x => Path.Combine(x.Descriptor.Location, x.Descriptor.Name)); + var moduleLocations = modules.Select(x => Path.Combine(x.Location, x.Name)); var moduleViewEngines = _viewEngineProviders .Select(x => x.CreateModulesViewEngine(new CreateModulesViewEngineParams { VirtualPaths = moduleLocations })); Logger.Debug("Module locations:\r\n\t-{0}", string.Join("\r\n\t-", moduleLocations.ToArray())); From 18bba7873b20da92fa43dfda33abce443f96baab Mon Sep 17 00:00:00 2001 From: Nathan Heskew Date: Tue, 27 Apr 2010 11:24:06 -0700 Subject: [PATCH 3/5] Adding some UI to manage module features --HG-- branch : dev --- src/Orchard.Specs/Modules.feature | 16 +++++- src/Orchard.Specs/Modules.feature.cs | 46 ++++++++++++++-- .../Modules/Orchard.Modules/AdminMenu.cs | 4 +- .../Controllers/AdminController.cs | 37 ++++++++++++- .../Orchard.Modules/Orchard.Modules.csproj | 10 ++++ .../Modules/Orchard.Modules/Permissions.cs | 3 +- .../Modules/Orchard.Modules/Routes.cs | 41 +++++++++++++++ .../Routing/ModuleNameConstraint.cs | 27 ++++++++++ .../Orchard.Modules/Services/ModuleService.cs | 52 +++++++++++++++---- .../ViewModels/FeatureListViewModel.cs | 9 ++++ .../ViewModels/ModuleEditViewModel.cs | 7 +++ .../Orchard.Modules/Views/Admin/Edit.ascx | 5 ++ .../Orchard.Modules/Views/Admin/Features.ascx | 33 ++++++++++++ .../Orchard.Modules/Views/Admin/Index.ascx | 16 ++++-- src/Orchard/Modules/IModuleService.cs | 4 ++ 15 files changed, 286 insertions(+), 24 deletions(-) create mode 100644 src/Orchard.Web/Modules/Orchard.Modules/Routes.cs create mode 100644 src/Orchard.Web/Modules/Orchard.Modules/Routing/ModuleNameConstraint.cs create mode 100644 src/Orchard.Web/Modules/Orchard.Modules/ViewModels/FeatureListViewModel.cs create mode 100644 src/Orchard.Web/Modules/Orchard.Modules/ViewModels/ModuleEditViewModel.cs create mode 100644 src/Orchard.Web/Modules/Orchard.Modules/Views/Admin/Edit.ascx create mode 100644 src/Orchard.Web/Modules/Orchard.Modules/Views/Admin/Features.ascx diff --git a/src/Orchard.Specs/Modules.feature b/src/Orchard.Specs/Modules.feature index 63fbb1c6a..718784b3a 100644 --- a/src/Orchard.Specs/Modules.feature +++ b/src/Orchard.Specs/Modules.feature @@ -3,9 +3,21 @@ As a root Orchard system operator I want to install and enable modules and enable features -Scenario: Default modules are listed +Scenario: Installed modules are listed Given I have installed Orchard When I go to "admin/modules" - Then I should see "Installed Modules" + Then I should see "

Installed Modules

" And I should see "

Themes

" And the status should be 200 OK + +Scenario: Edit module shows its features + Given I have installed Orchard + When I go to "admin/modules/Edit/Orchard.Themes" + Then I should see "

Edit Module: Themes

" + And the status should be 200 OK + +Scenario: Features of installed modules are listed + Given I have installed Orchard + When I go to "admin/modules/features" + Then I should see "

Available Features

" + And the status should be 200 OK \ No newline at end of file diff --git a/src/Orchard.Specs/Modules.feature.cs b/src/Orchard.Specs/Modules.feature.cs index 2090eff59..67ca158e7 100644 --- a/src/Orchard.Specs/Modules.feature.cs +++ b/src/Orchard.Specs/Modules.feature.cs @@ -51,10 +51,10 @@ namespace Orchard.Specs } [NUnit.Framework.TestAttribute()] - [NUnit.Framework.DescriptionAttribute("Default modules are listed")] - public virtual void DefaultModulesAreListed() + [NUnit.Framework.DescriptionAttribute("Installed modules are listed")] + public virtual void InstalledModulesAreListed() { - TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Default modules are listed", ((string[])(null))); + TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Installed modules are listed", ((string[])(null))); #line 6 this.ScenarioSetup(scenarioInfo); #line 7 @@ -62,11 +62,49 @@ this.ScenarioSetup(scenarioInfo); #line 8 testRunner.When("I go to \"admin/modules\""); #line 9 - testRunner.Then("I should see \"Installed Modules\""); + testRunner.Then("I should see \"

Installed Modules

\""); #line 10 testRunner.And("I should see \"

Themes

\""); #line 11 testRunner.And("the status should be 200 OK"); +#line hidden + testRunner.CollectScenarioErrors(); + } + + [NUnit.Framework.TestAttribute()] + [NUnit.Framework.DescriptionAttribute("Edit module shows its features")] + public virtual void EditModuleShowsItsFeatures() + { + TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Edit module shows its features", ((string[])(null))); +#line 13 +this.ScenarioSetup(scenarioInfo); +#line 14 + testRunner.Given("I have installed Orchard"); +#line 15 + testRunner.When("I go to \"admin/modules/Edit/Orchard.Themes\""); +#line 16 + testRunner.Then("I should see \"

Edit Module: Themes

\""); +#line 17 + testRunner.And("the status should be 200 OK"); +#line hidden + testRunner.CollectScenarioErrors(); + } + + [NUnit.Framework.TestAttribute()] + [NUnit.Framework.DescriptionAttribute("Features of installed modules are listed")] + public virtual void FeaturesOfInstalledModulesAreListed() + { + TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Features of installed modules are listed", ((string[])(null))); +#line 19 +this.ScenarioSetup(scenarioInfo); +#line 20 + testRunner.Given("I have installed Orchard"); +#line 21 + testRunner.When("I go to \"admin/modules/features\""); +#line 22 + testRunner.Then("I should see \"

Available Features

\""); +#line 23 + testRunner.And("the status should be 200 OK"); #line hidden testRunner.CollectScenarioErrors(); } diff --git a/src/Orchard.Web/Modules/Orchard.Modules/AdminMenu.cs b/src/Orchard.Web/Modules/Orchard.Modules/AdminMenu.cs index 951e25210..d12009d21 100644 --- a/src/Orchard.Web/Modules/Orchard.Modules/AdminMenu.cs +++ b/src/Orchard.Web/Modules/Orchard.Modules/AdminMenu.cs @@ -8,7 +8,9 @@ namespace Orchard.Modules { builder.Add("Modules", "10", menu => menu .Add("Manage Modules", "1.0", item => item.Action("Index", "Admin", new { area = "Orchard.Modules" }) - .Permission(Permissions.ManageModules))); + .Permission(Permissions.ManageModules)) + .Add("Manage Features", "2.0", item => item.Action("Features", "Admin", new { area = "Orchard.Modules" }) + .Permission(Permissions.ManageFeatures))); } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Modules/Controllers/AdminController.cs b/src/Orchard.Web/Modules/Orchard.Modules/Controllers/AdminController.cs index e9ae73f24..8b7704dad 100644 --- a/src/Orchard.Web/Modules/Orchard.Modules/Controllers/AdminController.cs +++ b/src/Orchard.Web/Modules/Orchard.Modules/Controllers/AdminController.cs @@ -1,17 +1,50 @@ -using System.Web.Mvc; +using System; +using System.Web.Mvc; +using Orchard.Localization; using Orchard.Modules.ViewModels; +using Orchard.Mvc.Results; namespace Orchard.Modules.Controllers { public class AdminController : Controller { private readonly IModuleService _moduleService; - public AdminController(IModuleService moduleService) { + public AdminController(IOrchardServices services, IModuleService moduleService) { + Services = services; _moduleService = moduleService; + T = NullLocalizer.Instance; } + private Localizer T { get; set; } + public IOrchardServices Services { get; set; } + public ActionResult Index() { + if (!Services.Authorizer.Authorize(Permissions.ManageModules, T("Not allowed to manage modules"))) + return new HttpUnauthorizedResult(); + var modules = _moduleService.GetInstalledModules(); return View(new ModulesIndexViewModel {Modules = modules}); } + + public ActionResult Edit(string moduleName) { + if (!Services.Authorizer.Authorize(Permissions.ManageModules, T("Not allowed to edit module"))) + return new HttpUnauthorizedResult(); + + var module = _moduleService.GetModuleByName(moduleName); + + if (module == null) + return new NotFoundResult(); + + return View(new ModuleEditViewModel { + Name = module.DisplayName + }); + } + + public ActionResult Features() { + if (!Services.Authorizer.Authorize(Permissions.ManageFeatures, T("Not allowed to manage features"))) + return new HttpUnauthorizedResult(); + + var features = _moduleService.GetAvailableFeatures(); + return View(new FeatureListViewModel {Features = features}); + } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Modules/Orchard.Modules.csproj b/src/Orchard.Web/Modules/Orchard.Modules/Orchard.Modules.csproj index 2a7864520..4b092dbcc 100644 --- a/src/Orchard.Web/Modules/Orchard.Modules/Orchard.Modules.csproj +++ b/src/Orchard.Web/Modules/Orchard.Modules/Orchard.Modules.csproj @@ -63,10 +63,14 @@ + + + + @@ -81,8 +85,14 @@ + + + + + +