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.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.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 @@
+
+
+
+
+
+