--HG--
branch : dev
This commit is contained in:
Renaud Paquay
2010-04-23 16:31:50 -07:00
142 changed files with 3280 additions and 672 deletions

View File

@@ -11,3 +11,4 @@ glob:*.sln.cache
glob:src/Orchard.Web/Modules/Orchard.DevTools/Module.txt
glob:src/Orchard.Web/Modules/Orchard.Sandbox/Module.txt
glob:src/Orchard.Web/Media/*
glob:desktop.ini

Binary file not shown.

View File

@@ -72,20 +72,6 @@ namespace Orchard.Core.Tests.Common.Providers {
Assert.That(item.Record.OwnerId, Is.EqualTo(0));
}
[Test,Ignore("This testing is still being worked out")]
public void OwnerShouldBeAuthenticatedUserIfAvailable() {
var contentManager = _container.Resolve<IContentManager>();
var user = contentManager.New<IUser>("user");
_authn.Setup(x => x.GetAuthenticatedUser()).Returns(user);
var item = contentManager.Create<CommonAspect>("test-item", init => { });
ClearSession();
Assert.That(item.Record.OwnerId, Is.EqualTo(6655321));
}
[Test]
public void PublishingShouldSetPublishUtc() {
var contentManager = _container.Resolve<IContentManager>();

View File

@@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
using TechTalk.SpecFlow;
namespace Orchard.Specs.Bindings {
public class BindingBase {
protected static T Binding<T>() {
return (T)ScenarioContext.Current.GetBindingInstance(typeof(T));
}
protected Table TableData<T>(params T[] rows) {
return BuildTable(rows);
}
protected Table TableData<T>(IEnumerable<T> rows) {
return BuildTable(rows);
}
private Table BuildTable<T>(IEnumerable<T> rows) {
var properties = typeof(T).GetProperties();
var table = new Table(properties.Select(x => x.Name).ToArray());
foreach (var row in rows) {
var row1 = row;
table.AddRow(properties.Select(p => Convert.ToString(p.GetValue(row1, null))).ToArray());
}
return table;
}
}
}

View File

@@ -0,0 +1,57 @@
using System.Diagnostics;
using System.Linq;
using System.Text;
using Orchard.Environment.Configuration;
using Orchard.Environment.Topology;
using Orchard.Environment.Topology.Models;
using Orchard.Specs.Hosting.Orchard.Web;
using TechTalk.SpecFlow;
namespace Orchard.Specs.Bindings {
[Binding]
public class OrchardSiteFactory : BindingBase {
[Given(@"I have installed Orchard")]
public void GivenIHaveInstalledOrchard() {
var webApp = Binding<WebAppHosting>();
webApp.GivenIHaveACleanSiteWith(TableData(
new { extension = "module", names = "Orchard.Setup, Orchard.Modules, Orchard.Themes, Orchard.Users, Orchard.Roles, Orchard.Pages, Orchard.Comments, TinyMce" },
new { extension = "core", names = "Common, Dashboard, Feeds, HomePage, Navigation, Scheduling, Settings, XmlRpc" },
new { extension = "theme", names = "SafeMode, Classic" }));
webApp.WhenIGoTo("Setup");
webApp.WhenIFillIn(TableData(
new { name = "SiteName", value = "My Site" },
new { name = "AdminPassword", value = "6655321" }));
webApp.WhenIHit("Finish Setup");
}
[Given(@"I have installed ""(.*)\""")]
public void GivenIHaveInstalled(string name) {
Binding<WebAppHosting>().GivenIHaveModule(name);
GivenIHaveEnabled(name);
}
[Given(@"I have enabled ""(.*)\""")]
public void GivenIHaveEnabled(string name) {
var webApp = Binding<WebAppHosting>();
webApp.Host.Execute(() => {
using (var environment = MvcApplication.CreateStandaloneEnvironment("Default")) {
var descriptorManager = environment.Resolve<IShellDescriptorManager>();
var descriptor = descriptorManager.GetShellDescriptor();
descriptorManager.UpdateShellDescriptor(
descriptor.SerialNumber,
descriptor.EnabledFeatures.Concat(new[] { new ShellFeature { Name = name } }),
descriptor.Parameters);
}
Trace.WriteLine("This call to Host.Reinitialize should not be needed, eventually");
MvcApplication.Host.Reinitialize_Obsolete();
});
}
}
}

View File

@@ -1,12 +1,18 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Remoting;
using System.Web;
using System.Web.Hosting;
using System.Xml.Linq;
using Castle.Core.Logging;
using HtmlAgilityPack;
using log4net.Appender;
using log4net.Core;
using log4net.Repository;
using Orchard.Specs.Hosting;
using Orchard.Specs.Util;
using TechTalk.SpecFlow;
@@ -20,6 +26,10 @@ namespace Orchard.Specs.Bindings {
private HtmlDocument _doc;
private MessageSink _messages;
public WebHost Host {
get { return _webHost; }
}
[Given(@"I have a clean site")]
public void GivenIHaveACleanSite() {
GivenIHaveACleanSiteBasedOn("Orchard.Web");
@@ -29,28 +39,55 @@ namespace Orchard.Specs.Bindings {
[Given(@"I have a clean site based on (.*)")]
public void GivenIHaveACleanSiteBasedOn(string siteFolder) {
_webHost = new WebHost();
_webHost.Initialize(siteFolder, "/");
var sink = new MessageSink();
_webHost.Execute(() => {
HostingTraceListener.SetHook(msg => sink.Receive(msg));
Host.Initialize(siteFolder, "/");
var shuttle = new Shuttle();
Host.Execute(() => {
log4net.Config.BasicConfigurator.Configure(new CastleAppender());
HostingTraceListener.SetHook(msg => shuttle._sink.Receive(msg));
});
_messages = sink;
_messages = shuttle._sink;
}
private class CastleAppender : IAppender {
public void Close() { }
public string Name { get; set; }
public void DoAppend(LoggingEvent loggingEvent) {
var traceLoggerFactory = new TraceLoggerFactory();
var logger = traceLoggerFactory.Create(loggingEvent.LoggerName);
if (loggingEvent.Level <= Level.Debug)
logger.Debug(loggingEvent.RenderedMessage);
else if (loggingEvent.Level <= Level.Info)
logger.Info(loggingEvent.RenderedMessage);
else if (loggingEvent.Level <= Level.Warn)
logger.Warn(loggingEvent.RenderedMessage);
else if (loggingEvent.Level <= Level.Error)
logger.Error(loggingEvent.RenderedMessage);
else
logger.Fatal(loggingEvent.RenderedMessage);
}
}
[Serializable]
class Shuttle {
public readonly MessageSink _sink = new MessageSink();
}
[Given(@"I have module ""(.*)""")]
public void GivenIHaveModule(string moduleName) {
_webHost.CopyExtension("Modules", moduleName);
Host.CopyExtension("Modules", moduleName);
}
[Given(@"I have theme ""(.*)""")]
public void GivenIHaveTheme(string themeName) {
_webHost.CopyExtension("Themes", themeName);
Host.CopyExtension("Themes", themeName);
}
[Given(@"I have core ""(.*)""")]
public void GivenIHaveCore(string moduleName) {
_webHost.CopyExtension("Core", moduleName);
Host.CopyExtension("Core", moduleName);
}
[Given(@"I have a clean site with")]
@@ -84,7 +121,7 @@ namespace Orchard.Specs.Bindings {
[When(@"I go to ""(.*)""")]
public void WhenIGoTo(string urlPath) {
_details = _webHost.SendRequest(urlPath);
_details = Host.SendRequest(urlPath);
_doc = new HtmlDocument();
_doc.Load(new StringReader(_details.ResponseText));
}
@@ -126,11 +163,21 @@ namespace Orchard.Specs.Bindings {
.GroupBy(elt => elt.GetAttributeValue("name", elt.GetAttributeValue("id", "")), elt => elt.GetAttributeValue("value", ""))
.ToDictionary(elt => elt.Key, elt => (IEnumerable<string>)elt);
_details = _webHost.SendRequest(urlPath, inputs);
_details = Host.SendRequest(urlPath, inputs);
_doc = new HtmlDocument();
_doc.Load(new StringReader(_details.ResponseText));
}
[When(@"I am redirected")]
public void WhenIAmRedirected() {
var urlPath = "";
if (_details.ResponseHeaders.TryGetValue("Location", out urlPath)) {
WhenIGoTo(urlPath);
}
else {
Assert.Fail("No Location header returned");
}
}
[Then(@"the status should be (.*) (.*)")]
public void ThenTheStatusShouldBe(int statusCode, string statusDescription) {

View File

@@ -1,11 +1,13 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
namespace Orchard.Specs.Hosting {
public class MessageSink : MarshalByRefObject {
readonly IList<string> _messages = new List<string>();
public void Receive(string message) {
Trace.WriteLine(" "+message);
_messages.Add(message);
}
}

View File

@@ -1,13 +1,36 @@
<system.diagnostics>
<trace autoflush="true"/>
<sources>
<source name="Default" switchValue="Verbose">
<source name="Default" switchValue="Warning">
<listeners>
<add name="CaptureTraceMessages" />
</listeners>
</source>
<source name="Orchard" switchValue="Verbose">
<listeners>
<add name="CaptureTraceMessages" />
</listeners>
</source>
<source name="Orchard.Data.SessionLocator" switchValue="Information">
<listeners>
<add name="CaptureTraceMessages" />
</listeners>
</source>
<source name="NHibernate.SQL" switchValue="Verbose">
<listeners>
<add name="CaptureTraceMessages" />
</listeners>
</source>
<source name="Orchard.Mvc.ViewEngines.WebFormsViewEngineProvider" switchValue="Warning">
<listeners>
<add name="CaptureTraceMessages" />
</listeners>
</source>
<!--<source name="Orchard.Localization.Text" switchValue="Warning"/>
<source name="Orchard.Mvc.ViewEngines.WebFormsViewEngineProvider" switchValue="Warning"/>-->
</sources>
<sharedListeners>
<add name="CaptureTraceMessages" type="Orchard.Specs.Hosting.HostingTraceListener, Orchard.Specs" initializeData="" />
<add name="CaptureTraceMessages" type="Orchard.Specs.Hosting.HostingTraceListener, Orchard.Specs" initializeData="" />
</sharedListeners>
</system.diagnostics>

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="autofac" type="Autofac.Configuration.SectionHandler, Autofac.Configuration"/>
</configSections>
<autofac defaultAssembly="Orchard.Framework">
<components>
<!--<component instance-scope="single-instance"
type="Orchard.Environment.Configuration.AzureBlobTenantManager"
service="Orchard.Environment.Configuration.IShellSettingsManager">
<parameters>
<parameter name="account" value="devstoreaccount1"/>
<parameter name="key" value="Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw=="/>
<parameter name="container" value="mycontainer"/>
</parameters>
</component>-->
</components>
</autofac>
</configuration>

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="autofac" type="Autofac.Configuration.SectionHandler, Autofac.Configuration"/>
</configSections>
<autofac defaultAssembly="Orchard.Framework">
<components>
<component instance-scope="single-instance"
type="Orchard.Specs.Hosting.TraceEnabledSessionFactoryBuilder, Orchard.Specs"
service="Orchard.Data.Builders.ISessionFactoryBuilder, Orchard.Framework"/>
</components>
</autofac>
</configuration>

View File

@@ -1,21 +1,26 @@
using System;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using Autofac;
using Autofac.Integration.Web;
using Orchard.Environment;
using Orchard.Environment.Configuration;
namespace Orchard.Specs.Hosting.Orchard.Web
{
public class MvcApplication : HttpApplication
{
private static IContainer _hostContainer;
private static IOrchardHost _host;
protected void Application_Start()
{
_host = OrchardStarter.CreateHost(MvcSingletons);
_host.Initialize();
_hostContainer = OrchardStarter.CreateHostContainer(MvcSingletons);
_host = _hostContainer.Resolve<IOrchardHost>();
Host.Initialize();
var route = RouteTable.Routes.MapRoute("foo", "hello-world", new { controller = "Home", action = "Index" });
route.RouteHandler = new HelloYetAgainHandler();
@@ -24,12 +29,12 @@ namespace Orchard.Specs.Hosting.Orchard.Web
protected void Application_BeginRequest()
{
_host.BeginRequest();
Host.BeginRequest();
}
protected void Application_EndRequest()
{
_host.EndRequest();
Host.EndRequest();
}
protected void MvcSingletons(ContainerBuilder builder)
@@ -41,5 +46,13 @@ namespace Orchard.Specs.Hosting.Orchard.Web
builder.RegisterInstance(ViewEngines.Engines);
}
public static IOrchardHost Host {
get { return _host; }
}
public static IStandaloneEnvironment CreateStandaloneEnvironment(string name) {
var settings = _hostContainer.Resolve<IShellSettingsManager>().LoadSettings().SingleOrDefault(x => x.Name == name);
return Host.CreateStandaloneEnvironment(settings);
}
}
}

View File

@@ -7,6 +7,11 @@ using HtmlAgilityPack;
namespace Orchard.Specs.Hosting {
[Serializable]
public class RequestDetails {
public RequestDetails() {
RequestHeaders = new Dictionary<string, string>();
ResponseHeaders = new Dictionary<string, string>();
}
public string UrlPath { get; set; }
public string Page { get; set; }
public string Query { get; set; }
@@ -15,5 +20,8 @@ namespace Orchard.Specs.Hosting {
public int StatusCode { get; set; }
public string StatusDescription { get; set; }
public string ResponseText { get; set; }
public IDictionary<string, string> RequestHeaders { get; set; }
public IDictionary<string, string> ResponseHeaders { get; set; }
}
}

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
@@ -11,6 +12,7 @@ using Orchard.Specs.Util;
namespace Orchard.Specs.Hosting {
public static class RequestExtensions {
public static RequestDetails SendRequest(this WebHost webHost, string urlPath, IDictionary<string, IEnumerable<string>> postData) {
var physicalPath = Bleroy.FluentPath.Path.Get(webHost.PhysicalDirectory);
var details = new RequestDetails {
@@ -20,20 +22,31 @@ namespace Orchard.Specs.Hosting {
.GetRelativePath(physicalPath),
};
if (!string.IsNullOrEmpty(webHost.Cookies)) {
details.RequestHeaders.Add("Cookie", webHost.Cookies);
}
if (postData != null) {
var requestBodyText = postData
.SelectMany(kv=>kv.Value.Select(v=>new{k=kv.Key, v}))
.Select((kv, n) => new {p = HttpUtility.UrlEncode(kv.k) + "=" + HttpUtility.UrlEncode(kv.v), n})
.SelectMany(kv => kv.Value.Select(v => new { k = kv.Key, v }))
.Select((kv, n) => new { p = HttpUtility.UrlEncode(kv.k) + "=" + HttpUtility.UrlEncode(kv.v), n })
.Aggregate("", (a, x) => a + (x.n == 0 ? "" : "&") + x.p);
details.PostData = Encoding.Default.GetBytes(requestBodyText);
}
webHost.Execute(() => {
var output = new StringWriter();
HttpRuntime.ProcessRequest(new Worker(details, output));
var worker = new Worker(details, output);
HttpRuntime.ProcessRequest(worker);
details.ResponseText = output.ToString();
});
string setCookie;
if (details.ResponseHeaders.TryGetValue("Set-Cookie", out setCookie)) {
Trace.WriteLine(string.Format("Set-Cookie: {0}", setCookie));
webHost.Cookies = (webHost.Cookies + ';' + setCookie.Split(';').FirstOrDefault()).Trim(';');
}
return details;
}
@@ -71,6 +84,11 @@ namespace Orchard.Specs.Hosting {
if (_details.PostData != null)
return PostContentType;
}
else if (index == HeaderCookie) {
string value;
if (_details.RequestHeaders.TryGetValue("Cookie", out value))
return value;
}
return base.GetKnownRequestHeader(index);
}
@@ -89,6 +107,24 @@ namespace Orchard.Specs.Hosting {
base.SendStatus(statusCode, statusDescription);
}
public override void SendKnownResponseHeader(int index, string value) {
if (index == HeaderSetCookie) {
_details.ResponseHeaders.Add("Set-Cookie", value);
}
else if (index == HeaderLocation) {
_details.ResponseHeaders.Add("Location", value);
}
else {
_details.ResponseHeaders.Add("known header #" + index, value);
}
base.SendKnownResponseHeader(index, value);
}
public override void SendUnknownResponseHeader(string name, string value) {
_details.ResponseHeaders.Add(name, value);
base.SendUnknownResponseHeader(name, value);
}
public override void SendResponseFromFile(string filename, long offset, long length) {
_output.Write(File.ReadAllText(filename));
}

View File

@@ -0,0 +1,3 @@
<%@ Page %>
<% Response.Cookies.Add(new HttpCookie("foo", "bar")); %>

View File

@@ -0,0 +1,8 @@
<%@ Page %>
<ul>
<% foreach(string name in Request.Cookies) {%>
<li>
<%=name %>:<%=Request.Cookies[name].Value %></li>
<%}%>
</ul>

View File

@@ -1,5 +1,17 @@
<%@ Page %>
<p>Hello again</p>
<p>RawUrl: <%=Page.Request.RawUrl%></p>
<p>Moving along to <a href="/hello-world">next page</a></p>
<p>
Hello again</p>
<p>
RawUrl:
<%=Page.Request.RawUrl%></p>
<p>
Moving along to <a href="/hello-world">next page</a></p>
<p>
<form action="<%=ResolveUrl("~/Simple/Results.aspx") %>" method="post">
<input type="text" name="passthrough1" value="alpha" />
<input type="hidden" name="passthrough2" value="beta" />
<input type="hidden" name="input1" />
<input type="submit" value="Go!" />
</form>
</p>

View File

@@ -0,0 +1,5 @@
<%@ Page %>
<%
Response.Redirect("Page.aspx"); %>

View File

@@ -0,0 +1,7 @@
<%@ Page %>
<ul>
<li>passthrough1:<%=Server.HtmlEncode(Request.Form.Get("passthrough1")) %></li>
<li>passthrough2:<%=Server.HtmlEncode(Request.Form.Get("passthrough2")) %></li>
<li>input1:<%=Server.HtmlEncode(Request.Form.Get("input1")) %></li>
</ul>

View File

@@ -42,7 +42,7 @@
affects performance, set this value to true only
during development.
-->
<compilation debug="true">
<compilation debug="true" defaultLanguage="cs">
<assemblies>
<add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>

View File

@@ -0,0 +1,24 @@
using FluentNHibernate.Cfg.Db;
using NHibernate;
using Orchard.Data.Builders;
namespace Orchard.Specs.Hosting {
public class TraceEnabledSessionFactoryBuilder : ISessionFactoryBuilder {
public TraceEnabledSessionFactoryBuilder() {
}
public ISessionFactory BuildSessionFactory(SessionFactoryParameters parameters) {
var builder = new TraceEnabledBuilder(parameters.DataFolder, parameters.ConnectionString);
return builder.BuildSessionFactory(parameters);
}
class TraceEnabledBuilder : SQLiteBuilder {
public TraceEnabledBuilder(string dataFolder, string connectionString) : base(dataFolder, connectionString) {
}
protected override IPersistenceConfigurer GetPersistenceConfigurer(bool createDatabase) {
var config = (SQLiteConfiguration)base.GetPersistenceConfigurer(createDatabase);
return config.ShowSql();
}
}
}
}

View File

@@ -46,6 +46,9 @@ namespace Orchard.Specs.Hosting {
public string PhysicalDirectory { get; private set; }
public string VirtualDirectory { get; private set; }
public string Cookies { get; set; }
public void Execute(Action action) {
var shuttleSend = new SerializableDelegate<Action>(action);

View File

@@ -0,0 +1,11 @@
Feature: Module management
In order add and enable features
As a root Orchard system operator
I want to install and enable modules and enable features
Scenario: Default modules are listed
Given I have installed Orchard
When I go to "admin/modules"
Then I should see "Installed Modules"
And I should see "<h3>Themes</h3>"
And the status should be 200 OK

74
src/Orchard.Specs/Modules.feature.cs generated Normal file
View File

@@ -0,0 +1,74 @@
// ------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by SpecFlow (http://www.specflow.org/).
// SpecFlow Version:1.2.0.0
// Runtime Version:2.0.50727.4927
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
// ------------------------------------------------------------------------------
namespace Orchard.Specs
{
using TechTalk.SpecFlow;
[NUnit.Framework.TestFixtureAttribute()]
[NUnit.Framework.DescriptionAttribute("Module management")]
public partial class ModuleManagementFeature
{
private static TechTalk.SpecFlow.ITestRunner testRunner;
#line 1 "Modules.feature"
#line hidden
[NUnit.Framework.TestFixtureSetUpAttribute()]
public virtual void FeatureSetup()
{
testRunner = TechTalk.SpecFlow.TestRunnerManager.GetTestRunner();
TechTalk.SpecFlow.FeatureInfo featureInfo = new TechTalk.SpecFlow.FeatureInfo(new System.Globalization.CultureInfo("en-US"), "Module management", "In order add and enable features\r\nAs a root Orchard system operator\r\nI want to in" +
"stall and enable modules and enable features", ((string[])(null)));
testRunner.OnFeatureStart(featureInfo);
}
[NUnit.Framework.TestFixtureTearDownAttribute()]
public virtual void FeatureTearDown()
{
testRunner.OnFeatureEnd();
testRunner = null;
}
public virtual void ScenarioSetup(TechTalk.SpecFlow.ScenarioInfo scenarioInfo)
{
testRunner.OnScenarioStart(scenarioInfo);
}
[NUnit.Framework.TearDownAttribute()]
public virtual void ScenarioTearDown()
{
testRunner.OnScenarioEnd();
}
[NUnit.Framework.TestAttribute()]
[NUnit.Framework.DescriptionAttribute("Default modules are listed")]
public virtual void DefaultModulesAreListed()
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Default modules are listed", ((string[])(null)));
#line 6
this.ScenarioSetup(scenarioInfo);
#line 7
testRunner.Given("I have installed Orchard");
#line 8
testRunner.When("I go to \"admin/modules\"");
#line 9
testRunner.Then("I should see \"Installed Modules\"");
#line 10
testRunner.And("I should see \"<h3>Themes</h3>\"");
#line 11
testRunner.And("the status should be 200 OK");
#line hidden
testRunner.CollectScenarioErrors();
}
}
}

View File

@@ -0,0 +1,43 @@
Feature: Multiple tenant management
In order to host several isolated web applications
As a root Orchard system operator
I want to create and manage tenant configurations
Scenario: Default site is listed
Given I have installed Orchard
And I have installed "Orchard.MultiTenancy"
When I go to "Admin/MultiTenancy"
Then I should see "List of Site's Tenants"
And I should see "<td>Default</td>"
And the status should be 200 OK
Scenario: New tenant fields are required
Given I have installed Orchard
And I have installed "Orchard.MultiTenancy"
When I go to "Admin/MultiTenancy/Add"
And I hit "Save"
Then I should see "is required"
Scenario: A new tenant is created
Given I have installed Orchard
And I have installed "Orchard.MultiTenancy"
When I go to "Admin/MultiTenancy/Add"
And I fill in
| name | value |
| Name | Scott |
And I hit "Save"
And I am redirected
Then I should see "<td>Scott</td>"
And the status should be 200 OK
Scenario: A new tenant is created with uninitialized state
Given I have installed Orchard
And I have installed "Orchard.MultiTenancy"
When I go to "Admin/MultiTenancy/Add"
And I fill in
| name | value |
| Name | Scott |
And I hit "Save"
And I am redirected
Then I should see "<td>Uninitialized</td>"
And the status should be 200 OK

165
src/Orchard.Specs/MultiTenancy.feature.cs generated Normal file
View File

@@ -0,0 +1,165 @@
// ------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by SpecFlow (http://www.specflow.org/).
// SpecFlow Version:1.2.0.0
// Runtime Version:2.0.50727.3603
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
// ------------------------------------------------------------------------------
namespace Orchard.Specs
{
using TechTalk.SpecFlow;
[NUnit.Framework.TestFixtureAttribute()]
[NUnit.Framework.DescriptionAttribute("Multiple tenant management")]
public partial class MultipleTenantManagementFeature
{
private static TechTalk.SpecFlow.ITestRunner testRunner;
#line 1 "MultiTenancy.feature"
#line hidden
[NUnit.Framework.TestFixtureSetUpAttribute()]
public virtual void FeatureSetup()
{
testRunner = TechTalk.SpecFlow.TestRunnerManager.GetTestRunner();
TechTalk.SpecFlow.FeatureInfo featureInfo = new TechTalk.SpecFlow.FeatureInfo(new System.Globalization.CultureInfo("en-US"), "Multiple tenant management", "In order to host several isolated web applications\r\nAs a root Orchard system oper" +
"ator\r\nI want to create and manage tenant configurations", ((string[])(null)));
testRunner.OnFeatureStart(featureInfo);
}
[NUnit.Framework.TestFixtureTearDownAttribute()]
public virtual void FeatureTearDown()
{
testRunner.OnFeatureEnd();
testRunner = null;
}
public virtual void ScenarioSetup(TechTalk.SpecFlow.ScenarioInfo scenarioInfo)
{
testRunner.OnScenarioStart(scenarioInfo);
}
[NUnit.Framework.TearDownAttribute()]
public virtual void ScenarioTearDown()
{
testRunner.OnScenarioEnd();
}
[NUnit.Framework.TestAttribute()]
[NUnit.Framework.DescriptionAttribute("Default site is listed")]
public virtual void DefaultSiteIsListed()
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Default site is listed", ((string[])(null)));
#line 6
this.ScenarioSetup(scenarioInfo);
#line 7
testRunner.Given("I have installed Orchard");
#line 8
testRunner.And("I have installed \"Orchard.MultiTenancy\"");
#line 9
testRunner.When("I go to \"Admin/MultiTenancy\"");
#line 10
testRunner.Then("I should see \"List of Site\'s Tenants\"");
#line 11
testRunner.And("I should see \"<td>Default</td>\"");
#line 12
testRunner.And("the status should be 200 OK");
#line hidden
testRunner.CollectScenarioErrors();
}
[NUnit.Framework.TestAttribute()]
[NUnit.Framework.DescriptionAttribute("New tenant fields are required")]
public virtual void NewTenantFieldsAreRequired()
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("New tenant fields are required", ((string[])(null)));
#line 14
this.ScenarioSetup(scenarioInfo);
#line 15
testRunner.Given("I have installed Orchard");
#line 16
testRunner.And("I have installed \"Orchard.MultiTenancy\"");
#line 17
testRunner.When("I go to \"Admin/MultiTenancy/Add\"");
#line 18
testRunner.And("I hit \"Save\"");
#line 19
testRunner.Then("I should see \"is required\"");
#line hidden
testRunner.CollectScenarioErrors();
}
[NUnit.Framework.TestAttribute()]
[NUnit.Framework.DescriptionAttribute("A new tenant is created")]
public virtual void ANewTenantIsCreated()
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("A new tenant is created", ((string[])(null)));
#line 21
this.ScenarioSetup(scenarioInfo);
#line 22
testRunner.Given("I have installed Orchard");
#line 23
testRunner.And("I have installed \"Orchard.MultiTenancy\"");
#line 24
testRunner.When("I go to \"Admin/MultiTenancy/Add\"");
#line hidden
TechTalk.SpecFlow.Table table1 = new TechTalk.SpecFlow.Table(new string[] {
"name",
"value"});
table1.AddRow(new string[] {
"Name",
"Scott"});
#line 25
testRunner.And("I fill in", ((string)(null)), table1);
#line 28
testRunner.And("I hit \"Save\"");
#line 29
testRunner.And("I am redirected");
#line 30
testRunner.Then("I should see \"<td>Scott</td>\"");
#line 31
testRunner.And("the status should be 200 OK");
#line hidden
testRunner.CollectScenarioErrors();
}
[NUnit.Framework.TestAttribute()]
[NUnit.Framework.DescriptionAttribute("A new tenant is created with uninitialized state")]
public virtual void ANewTenantIsCreatedWithUninitializedState()
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("A new tenant is created with uninitialized state", ((string[])(null)));
#line 33
this.ScenarioSetup(scenarioInfo);
#line 34
testRunner.Given("I have installed Orchard");
#line 35
testRunner.And("I have installed \"Orchard.MultiTenancy\"");
#line 36
testRunner.When("I go to \"Admin/MultiTenancy/Add\"");
#line hidden
TechTalk.SpecFlow.Table table2 = new TechTalk.SpecFlow.Table(new string[] {
"name",
"value"});
table2.AddRow(new string[] {
"Name",
"Scott"});
#line 37
testRunner.And("I fill in", ((string)(null)), table2);
#line 40
testRunner.And("I hit \"Save\"");
#line 41
testRunner.And("I am redirected");
#line 42
testRunner.Then("I should see \"<td>Uninitialized</td>\"");
#line 43
testRunner.And("the status should be 200 OK");
#line hidden
testRunner.CollectScenarioErrors();
}
}
}

View File

@@ -43,6 +43,14 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\lib\autofac\Autofac.Integration.Web.Mvc.dll</HintPath>
</Reference>
<Reference Include="Castle.Core, Version=1.1.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\lib\Castle Windsor 2.0\bin\Castle.Core.dll</HintPath>
</Reference>
<Reference Include="FluentNHibernate, Version=1.0.0.0, Culture=neutral, PublicKeyToken=8aa435e3cb308880, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\lib\fluentnhibernate\FluentNHibernate.dll</HintPath>
</Reference>
<Reference Include="FluentPath, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\lib\fluentpath\FluentPath.dll</HintPath>
@@ -51,8 +59,16 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\lib\htmlagilitypack\HtmlAgilityPack.dll</HintPath>
</Reference>
<Reference Include="log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\lib\fluentnhibernate\log4net.dll</HintPath>
</Reference>
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<Reference Include="Microsoft.VisualStudio.TeamSystem.Data.UnitTesting, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<Reference Include="NHibernate, Version=2.1.2.4000, Culture=neutral, PublicKeyToken=aa95f207798dfdb4, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\lib\fluentnhibernate\NHibernate.dll</HintPath>
</Reference>
<Reference Include="nunit.framework, Version=2.5.2.9222, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\lib\nunit\nunit.framework.dll</HintPath>
@@ -86,12 +102,25 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Bindings\BindingBase.cs" />
<Compile Include="Bindings\OrchardSiteFactory.cs" />
<Compile Include="Hosting\MessageSink.cs" />
<Compile Include="Hosting\HostingTraceListener.cs" />
<Compile Include="Hosting\TraceEnabledSessionFactoryBuilder.cs" />
<Compile Include="Hosting\Simple.Web\HelloYetAgainHandler.cs" />
<Compile Include="Hosting\RequestExtensions.cs" />
<Compile Include="Hosting\RequestDetails.cs" />
<Compile Include="Hosting\Simple.Web\Global.asax.cs" />
<Compile Include="Modules.feature.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Modules.feature</DependentUpon>
</Compile>
<Compile Include="MultiTenancy.feature.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>MultiTenancy.feature</DependentUpon>
</Compile>
<Compile Include="Util\PathExtensions.cs" />
<Compile Include="WebHosting.feature.cs">
<DependentUpon>WebHosting.feature</DependentUpon>
@@ -129,12 +158,26 @@
<Content Include="Hosting\Orchard.Web\Themes\Web.config">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="Hosting\Orchard.Web\Config\Sites.Default.config">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None Include="Hosting\Orchard.Web\Config\Diagnostics.config">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<Content Include="Hosting\Simple.Web\Web.config">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="Hosting\Orchard.Web\Config\Host.config">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None Include="Modules.feature">
<Generator>SpecFlowSingleFileGenerator</Generator>
<LastGenOutput>Modules.feature.cs</LastGenOutput>
</None>
<None Include="MultiTenancy.feature">
<Generator>SpecFlowSingleFileGenerator</Generator>
<LastGenOutput>MultiTenancy.feature.cs</LastGenOutput>
</None>
<None Include="WebHosting.feature">
<Generator>SpecFlowSingleFileGenerator</Generator>
<LastGenOutput>WebHosting.feature.cs</LastGenOutput>
@@ -222,6 +265,18 @@
<Content Include="Hosting\Simple.Web\Global.asax">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="Hosting\Simple.Web\Simple\Cookie-Show.aspx">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="Hosting\Simple.Web\Simple\Cookie-Set.aspx">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="Hosting\Simple.Web\Simple\Redir.aspx">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="Hosting\Simple.Web\Simple\Results.aspx">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="Hosting\Simple.Web\Simple\Page.aspx">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>

View File

@@ -1,45 +1,48 @@
Feature: Setup
Feature: Setup
In order to install orchard
As a new user
I want to setup a new site from the default screen
Scenario: Root request shows setup form
Given I have a clean site
And I have module "Orchard.Setup"
And I have theme "SafeMode"
When I go to "/Default.aspx"
Then I should see "Welcome to Orchard"
And I should see "Finish Setup"
And the status should be 200 OK
Given I have a clean site
And I have module "Orchard.Setup"
And I have theme "SafeMode"
When I go to "/Default.aspx"
Then I should see "Welcome to Orchard"
And I should see "Finish Setup"
And the status should be 200 OK
Scenario: Setup folder also shows setup form
Given I have a clean site
And I have module "Orchard.Setup"
And I have theme "SafeMode"
When I go to "/Setup"
Then I should see "Welcome to Orchard"
And I should see "Finish Setup"
And the status should be 200 OK
Given I have a clean site
And I have module "Orchard.Setup"
And I have theme "SafeMode"
When I go to "/Setup"
Then I should see "Welcome to Orchard"
And I should see "Finish Setup"
And the status should be 200 OK
Scenario: Some of the initial form values are required
Given I have a clean site
And I have module "Orchard.Setup"
And I have theme "SafeMode"
When I go to "/Setup"
And I hit "Finish Setup"
Then I should see "Site name is required"
And I should see "Password is required"
Given I have a clean site
And I have module "Orchard.Setup"
And I have theme "SafeMode"
When I go to "/Setup"
And I hit "Finish Setup"
Then I should see "Site name is required"
And I should see "Password is required"
Scenario: Calling setup on a brand new install
Given I have a clean site with
| extension | names |
| module | Orchard.Setup, Orchard.Users, Orchard.Roles, Orchard.Pages, Orchard.Comments, TinyMce |
| core | Common, Dashboard, Feeds, HomePage, Navigation, Scheduling, Settings, Themes, XmlRpc |
| theme | SafeMode, Classic |
And I am on "/Setup"
When I fill in
| name | value |
| SiteName | My Site |
| AdminPassword | 6655321 |
And I hit "Finish Setup"
Then the status should be 302 Found
Given I have a clean site with
| extension | names |
| module | Orchard.Setup, Orchard.Users, Orchard.Roles, Orchard.Pages, Orchard.Comments, Orchard.Themes, TinyMce |
| core | Common, Dashboard, Feeds, HomePage, Navigation, Scheduling, Settings, XmlRpc |
| theme | SafeMode, Classic |
And I am on "/Setup"
When I fill in
| name | value |
| SiteName | My Site |
| AdminPassword | 6655321 |
And I hit "Finish Setup"
And I go to "/Default.aspx"
Then I should see "<h1>My Site</h1>"
And I should see "Welcome, <strong>admin</strong>!"
And I should see "you've successfully set-up your Orchard site"

View File

@@ -2,7 +2,7 @@
// <auto-generated>
// This code was generated by SpecFlow (http://www.specflow.org/).
// SpecFlow Version:1.2.0.0
// Runtime Version:2.0.50727.4927
// Runtime Version:2.0.50727.4200
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
@@ -58,19 +58,19 @@ namespace Orchard.Specs
#line 6
this.ScenarioSetup(scenarioInfo);
#line 7
testRunner.Given("I have a clean site");
testRunner.Given("I have a clean site");
#line 8
testRunner.And("I have module \"Orchard.Setup\"");
testRunner.And("I have module \"Orchard.Setup\"");
#line 9
testRunner.And("I have theme \"SafeMode\"");
testRunner.And("I have theme \"SafeMode\"");
#line 10
testRunner.When("I go to \"/Default.aspx\"");
testRunner.When("I go to \"/Default.aspx\"");
#line 11
testRunner.Then("I should see \"Welcome to Orchard\"");
testRunner.Then("I should see \"Welcome to Orchard\"");
#line 12
testRunner.And("I should see \"Finish Setup\"");
testRunner.And("I should see \"Finish Setup\"");
#line 13
testRunner.And("the status should be 200 OK");
testRunner.And("the status should be 200 OK");
#line hidden
testRunner.CollectScenarioErrors();
}
@@ -83,19 +83,19 @@ this.ScenarioSetup(scenarioInfo);
#line 15
this.ScenarioSetup(scenarioInfo);
#line 16
testRunner.Given("I have a clean site");
testRunner.Given("I have a clean site");
#line 17
testRunner.And("I have module \"Orchard.Setup\"");
testRunner.And("I have module \"Orchard.Setup\"");
#line 18
testRunner.And("I have theme \"SafeMode\"");
testRunner.And("I have theme \"SafeMode\"");
#line 19
testRunner.When("I go to \"/Setup\"");
testRunner.When("I go to \"/Setup\"");
#line 20
testRunner.Then("I should see \"Welcome to Orchard\"");
testRunner.Then("I should see \"Welcome to Orchard\"");
#line 21
testRunner.And("I should see \"Finish Setup\"");
testRunner.And("I should see \"Finish Setup\"");
#line 22
testRunner.And("the status should be 200 OK");
testRunner.And("the status should be 200 OK");
#line hidden
testRunner.CollectScenarioErrors();
}
@@ -108,19 +108,19 @@ this.ScenarioSetup(scenarioInfo);
#line 24
this.ScenarioSetup(scenarioInfo);
#line 25
testRunner.Given("I have a clean site");
testRunner.Given("I have a clean site");
#line 26
testRunner.And("I have module \"Orchard.Setup\"");
testRunner.And("I have module \"Orchard.Setup\"");
#line 27
testRunner.And("I have theme \"SafeMode\"");
testRunner.And("I have theme \"SafeMode\"");
#line 28
testRunner.When("I go to \"/Setup\"");
testRunner.When("I go to \"/Setup\"");
#line 29
testRunner.And("I hit \"Finish Setup\"");
testRunner.And("I hit \"Finish Setup\"");
#line 30
testRunner.Then("I should see \"Site name is required\"");
testRunner.Then("I should see \"Site name is required\"");
#line 31
testRunner.And("I should see \"Password is required\"");
testRunner.And("I should see \"Password is required\"");
#line hidden
testRunner.CollectScenarioErrors();
}
@@ -138,19 +138,18 @@ this.ScenarioSetup(scenarioInfo);
"names"});
table1.AddRow(new string[] {
"module",
"Orchard.Setup, Orchard.Users, Orchard.Roles, Orchard.Pages, Orchard.Comments, Tin" +
"yMce"});
"Orchard.Setup, Orchard.Users, Orchard.Roles, Orchard.Pages, Orchard.Comments, Orc" +
"hard.Themes, TinyMce"});
table1.AddRow(new string[] {
"core",
"Common, Dashboard, Feeds, HomePage, Navigation, Scheduling, Settings, Themes, Xml" +
"Rpc"});
"Common, Dashboard, Feeds, HomePage, Navigation, Scheduling, Settings, XmlRpc"});
table1.AddRow(new string[] {
"theme",
"SafeMode, Classic"});
#line 34
testRunner.Given("I have a clean site with", ((string)(null)), table1);
testRunner.Given("I have a clean site with", ((string)(null)), table1);
#line 39
testRunner.And("I am on \"/Setup\"");
testRunner.And("I am on \"/Setup\"");
#line hidden
TechTalk.SpecFlow.Table table2 = new TechTalk.SpecFlow.Table(new string[] {
"name",
@@ -162,11 +161,17 @@ this.ScenarioSetup(scenarioInfo);
"AdminPassword",
"6655321"});
#line 40
testRunner.When("I fill in", ((string)(null)), table2);
testRunner.When("I fill in", ((string)(null)), table2);
#line 44
testRunner.And("I hit \"Finish Setup\"");
testRunner.And("I hit \"Finish Setup\"");
#line 45
testRunner.Then("the status should be 302 Found");
testRunner.And("I go to \"/Default.aspx\"");
#line 46
testRunner.Then("I should see \"<h1>My Site</h1>\"");
#line 47
testRunner.And("I should see \"Welcome, <strong>admin</strong>!\"");
#line 48
testRunner.And("I should see \"you\'ve successfully set-up your Orchard site\"");
#line hidden
testRunner.CollectScenarioErrors();
}

View File

@@ -9,36 +9,12 @@ Scenario: Returning static files
Then I should see "Hello world!"
And the status should be 200 OK
Scenario: Returning static files 2
Given I have a clean site based on Simple.Web
When I go to "Content\Static.txt"
Then the status should be 200 OK
And I should see "Hello world!"
Scenario: Returning static files 3
Given I have a clean site based on Simple.Web
When I go to "/Static.txt"
Then the status should be 200 OK
And I should see "Hello world!"
Scenario: Returning static files 4
Given I have a clean site based on Simple.Web
When I go to "Static.txt"
Then the status should be 200 OK
And I should see "Hello world!"
Scenario: Returning web forms page
Given I have a clean site based on Simple.Web
When I go to "Simple/Page.aspx"
Then I should see "Hello again"
And the status should be 200 OK
Scenario: Returning web forms page 2
Given I have a clean site based on Simple.Web
When I go to "Simple\Page.aspx"
Then the status should be 200 OK
And I should see "Hello again"
Scenario: Returning a routed request
Given I have a clean site based on Simple.Web
When I go to "hello-world"
@@ -51,3 +27,26 @@ Scenario: Following a link
And I follow "next page"
Then the status should be 200 OK
And I should see "Hello yet again"
Scenario: Submitting a form with input, default, and hidden fields
Given I have a clean site based on Simple.Web
And I am on "/simple/page.aspx"
When I fill in
| name | value |
| input1 | gamma |
And I hit "Go!"
Then I should see "passthrough1:alpha"
And I should see "passthrough2:beta"
And I should see "input1:gamma"
Scenario: Cookies follow along your request
Given I have a clean site based on Simple.Web
When I go to "/simple/cookie-set.aspx"
And I go to "/simple/cookie-show.aspx"
Then I should see "foo:bar"
Scenario: Being redirected
Given I have a clean site based on Simple.Web
When I go to "/simple/redir.aspx"
And I am redirected
Then I should see "Hello again"

View File

@@ -2,7 +2,7 @@
// <auto-generated>
// This code was generated by SpecFlow (http://www.specflow.org/).
// SpecFlow Version:1.2.0.0
// Runtime Version:2.0.50727.4927
// Runtime Version:2.0.50727.4200
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
@@ -70,114 +70,38 @@ this.ScenarioSetup(scenarioInfo);
}
[NUnit.Framework.TestAttribute()]
[NUnit.Framework.DescriptionAttribute("Returning static files 2")]
public virtual void ReturningStaticFiles2()
[NUnit.Framework.DescriptionAttribute("Returning web forms page")]
public virtual void ReturningWebFormsPage()
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Returning static files 2", ((string[])(null)));
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Returning web forms page", ((string[])(null)));
#line 12
this.ScenarioSetup(scenarioInfo);
#line 13
testRunner.Given("I have a clean site based on Simple.Web");
#line 14
testRunner.When("I go to \"Content\\Static.txt\"");
#line 15
testRunner.Then("the status should be 200 OK");
#line 16
testRunner.And("I should see \"Hello world!\"");
#line hidden
testRunner.CollectScenarioErrors();
}
[NUnit.Framework.TestAttribute()]
[NUnit.Framework.DescriptionAttribute("Returning static files 3")]
public virtual void ReturningStaticFiles3()
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Returning static files 3", ((string[])(null)));
#line 18
this.ScenarioSetup(scenarioInfo);
#line 19
testRunner.Given("I have a clean site based on Simple.Web");
#line 20
testRunner.When("I go to \"/Static.txt\"");
#line 21
testRunner.Then("the status should be 200 OK");
#line 22
testRunner.And("I should see \"Hello world!\"");
#line hidden
testRunner.CollectScenarioErrors();
}
[NUnit.Framework.TestAttribute()]
[NUnit.Framework.DescriptionAttribute("Returning static files 4")]
public virtual void ReturningStaticFiles4()
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Returning static files 4", ((string[])(null)));
#line 24
this.ScenarioSetup(scenarioInfo);
#line 25
testRunner.Given("I have a clean site based on Simple.Web");
#line 26
testRunner.When("I go to \"Static.txt\"");
#line 27
testRunner.Then("the status should be 200 OK");
#line 28
testRunner.And("I should see \"Hello world!\"");
#line hidden
testRunner.CollectScenarioErrors();
}
[NUnit.Framework.TestAttribute()]
[NUnit.Framework.DescriptionAttribute("Returning web forms page")]
public virtual void ReturningWebFormsPage()
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Returning web forms page", ((string[])(null)));
#line 30
this.ScenarioSetup(scenarioInfo);
#line 31
testRunner.Given("I have a clean site based on Simple.Web");
#line 32
testRunner.When("I go to \"Simple/Page.aspx\"");
#line 33
#line 15
testRunner.Then("I should see \"Hello again\"");
#line 34
#line 16
testRunner.And("the status should be 200 OK");
#line hidden
testRunner.CollectScenarioErrors();
}
[NUnit.Framework.TestAttribute()]
[NUnit.Framework.DescriptionAttribute("Returning web forms page 2")]
public virtual void ReturningWebFormsPage2()
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Returning web forms page 2", ((string[])(null)));
#line 36
this.ScenarioSetup(scenarioInfo);
#line 37
testRunner.Given("I have a clean site based on Simple.Web");
#line 38
testRunner.When("I go to \"Simple\\Page.aspx\"");
#line 39
testRunner.Then("the status should be 200 OK");
#line 40
testRunner.And("I should see \"Hello again\"");
#line hidden
testRunner.CollectScenarioErrors();
}
[NUnit.Framework.TestAttribute()]
[NUnit.Framework.DescriptionAttribute("Returning a routed request")]
public virtual void ReturningARoutedRequest()
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Returning a routed request", ((string[])(null)));
#line 42
#line 18
this.ScenarioSetup(scenarioInfo);
#line 43
#line 19
testRunner.Given("I have a clean site based on Simple.Web");
#line 44
#line 20
testRunner.When("I go to \"hello-world\"");
#line 45
#line 21
testRunner.Then("the status should be 200 OK");
#line 46
#line 22
testRunner.And("I should see \"Hello yet again\"");
#line hidden
testRunner.CollectScenarioErrors();
@@ -188,18 +112,88 @@ this.ScenarioSetup(scenarioInfo);
public virtual void FollowingALink()
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Following a link", ((string[])(null)));
#line 24
this.ScenarioSetup(scenarioInfo);
#line 25
testRunner.Given("I have a clean site based on Simple.Web");
#line 26
testRunner.When("I go to \"/simple/page.aspx\"");
#line 27
testRunner.And("I follow \"next page\"");
#line 28
testRunner.Then("the status should be 200 OK");
#line 29
testRunner.And("I should see \"Hello yet again\"");
#line hidden
testRunner.CollectScenarioErrors();
}
[NUnit.Framework.TestAttribute()]
[NUnit.Framework.DescriptionAttribute("Submitting a form with input, default, and hidden fields")]
public virtual void SubmittingAFormWithInputDefaultAndHiddenFields()
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Submitting a form with input, default, and hidden fields", ((string[])(null)));
#line 31
this.ScenarioSetup(scenarioInfo);
#line 32
testRunner.Given("I have a clean site based on Simple.Web");
#line 33
testRunner.And("I am on \"/simple/page.aspx\"");
#line hidden
TechTalk.SpecFlow.Table table1 = new TechTalk.SpecFlow.Table(new string[] {
"name",
"value"});
table1.AddRow(new string[] {
"input1",
"gamma"});
#line 34
testRunner.When("I fill in", ((string)(null)), table1);
#line 37
testRunner.And("I hit \"Go!\"");
#line 38
testRunner.Then("I should see \"passthrough1:alpha\"");
#line 39
testRunner.And("I should see \"passthrough2:beta\"");
#line 40
testRunner.And("I should see \"input1:gamma\"");
#line hidden
testRunner.CollectScenarioErrors();
}
[NUnit.Framework.TestAttribute()]
[NUnit.Framework.DescriptionAttribute("Cookies follow along your request")]
public virtual void CookiesFollowAlongYourRequest()
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Cookies follow along your request", ((string[])(null)));
#line 42
this.ScenarioSetup(scenarioInfo);
#line 43
testRunner.Given("I have a clean site based on Simple.Web");
#line 44
testRunner.When("I go to \"/simple/cookie-set.aspx\"");
#line 45
testRunner.And("I go to \"/simple/cookie-show.aspx\"");
#line 46
testRunner.Then("I should see \"foo:bar\"");
#line hidden
testRunner.CollectScenarioErrors();
}
[NUnit.Framework.TestAttribute()]
[NUnit.Framework.DescriptionAttribute("Being redirected")]
public virtual void BeingRedirected()
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Being redirected", ((string[])(null)));
#line 48
this.ScenarioSetup(scenarioInfo);
#line 49
testRunner.Given("I have a clean site based on Simple.Web");
#line 50
testRunner.When("I go to \"/simple/page.aspx\"");
testRunner.When("I go to \"/simple/redir.aspx\"");
#line 51
testRunner.And("I follow \"next page\"");
testRunner.And("I am redirected");
#line 52
testRunner.Then("the status should be 200 OK");
#line 53
testRunner.And("I should see \"Hello yet again\"");
testRunner.Then("I should see \"Hello again\"");
#line hidden
testRunner.CollectScenarioErrors();
}

View File

@@ -87,7 +87,6 @@
<Compile Include="Roles\Controllers\AdminControllerTests.cs" />
<Compile Include="Roles\Services\RoleServiceTests.cs" />
<Compile Include="Settings\Topology\ShellDescriptorManagerTests.cs" />
<Compile Include="Setup\SetupControllerTests.cs" />
<Compile Include="Values.cs" />
<Compile Include="Users\Controllers\AdminControllerTests.cs" />
<Compile Include="Users\Services\MembershipServiceTests.cs" />

View File

@@ -34,19 +34,5 @@ namespace Orchard.Tests.Modules.Roles.Services {
Assert.That(roles, Has.Some.Property("Name").EqualTo("two"));
Assert.That(roles, Has.Some.Property("Name").EqualTo("three"));
}
[Test, Ignore("Permissions should be created first it appears?")]
public void PermissionRecordsShouldBeCreatedOnDemand() {
var service = _container.Resolve<IRoleService>();
service.CreateRole("one");
service.CreatePermissionForRole("one", "foo");
service.CreatePermissionForRole("one", "bar");
ClearSession();
var one = service.GetRoles().Single(x => x.Name == "one");
Assert.That(one.RolesPermissions, Has.Count.EqualTo(2));
Assert.That(one.RolesPermissions.Select(x => x.Permission.Name), Has.Some.EqualTo("foo"));
Assert.That(one.RolesPermissions.Select(x => x.Permission.Name), Has.Some.EqualTo("bar"));
}
}
}

View File

@@ -1,106 +0,0 @@
using System.IO;
using System.Linq;
using System.Web.Mvc;
using System.Web.Routing;
using Autofac;
using NUnit.Framework;
using Orchard.Environment;
using Orchard.Environment.AutofacUtil;
using Orchard.Environment.Configuration;
using Orchard.Setup.Controllers;
using Orchard.Setup.ViewModels;
using Orchard.UI.Notify;
namespace Orchard.Tests.Modules.Setup {
[TestFixture, Ignore("this can't be made to work")]
public class SetupControllerTests {
private string _tempFolder;
private ILifetimeScope _container;
[SetUp]
public void Init() {
//_tempFolder = Path.GetTempFileName();
//File.Delete(_tempFolder);
//Directory.CreateDirectory(_tempFolder);
//var hostContainer = OrchardStarter.CreateHostContainer(builder => {
// builder.RegisterInstance(new ControllerBuilder());
// builder.RegisterInstance(new ViewEngineCollection { new WebFormViewEngine() });
// builder.RegisterInstance(new RouteCollection());
// builder.RegisterInstance(new ModelBinderDictionary());
//});
//hostContainer.Resolve<IAppDataFolder>().SetBasePath(_tempFolder);
//var host = (DefaultOrchardHost)hostContainer.Resolve<IOrchardHost>();
//_container = host.CreateShellContainer_Obsolete().BeginLifetimeScope();
//var updater = new ContainerUpdater();
//updater.RegisterType<SetupController>();
//updater.Update(_container);
//var builder = new ContainerBuilder();
//builder.Register<SetupController>();
//builder.Register<Notifier>().As<INotifier>();
//builder.Register<DefaultOrchardHost>().As<IOrchardHost>();
//builder.Register<DatabaseMigrationManager>().As<IDatabaseMigrationManager>();
//builder.Register<ShellSettingsManager>().As<IShellSettingsManager>();
//builder.Register<TestAppDataFolder>().As<IAppDataFolder>();
//_container = builder.Build();
}
private string GetMessages() {
var notifier = _container.Resolve<INotifier>();
return notifier.List().Aggregate("", (a, b) => a + b.Message.ToString());
}
private SetupViewModel GetTestSetupModel() {
return new SetupViewModel {
AdminUsername = "test1",
AdminPassword = "test2",
DatabaseOptions = true,
SiteName = "test3"
};
}
[Test]
public void IndexNormallyReturnsWithDefaultAdminUsername() {
var controller = _container.Resolve<SetupController>();
var result = controller.Index();
Assert.That(result, Is.Not.Null);
Assert.That(result, Is.TypeOf<ViewResult>());
var viewResult = (ViewResult)result;
Assert.That(viewResult.ViewData.Model, Is.TypeOf<SetupViewModel>());
var model2 = (SetupViewModel)viewResult.ViewData.Model;
Assert.That(model2.AdminUsername, Is.EqualTo("admin"));
}
[Test]
public void SetupShouldCreateShellSettingsFile() {
var model = GetTestSetupModel();
var controller = _container.Resolve<SetupController>();
var result = controller.IndexPOST(model);
Assert.That(GetMessages(), Is.StringContaining("Setup succeeded"));
Assert.That(result, Is.Not.Null);
Assert.That(result, Is.TypeOf<RedirectResult>());
Assert.That(File.Exists(Path.Combine(_tempFolder, "Sites\\default.txt")));
}
[Test]
public void BuiltinDatabaseShouldCreateSQLiteFile() {
var model = GetTestSetupModel();
var controller = _container.Resolve<SetupController>();
var result = controller.IndexPOST(model);
Assert.That(GetMessages(), Is.StringContaining("Setup succeeded"));
Assert.That(result, Is.Not.Null);
Assert.That(result, Is.TypeOf<RedirectResult>());
Assert.That(File.Exists(Path.Combine(_tempFolder, "Sites\\default\\orchard.db")));
}
}
}

View File

@@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Autofac;
using Autofac.Builder;
using Autofac.Core;
using Autofac.Core.Activators.Delegate;
using Autofac.Core.Lifetime;
using Autofac.Core.Registration;
using NUnit.Framework;
namespace Orchard.Tests.Environment.AutofacUtil {
[TestFixture]
public class AutofacTests {
public interface IFoo { }
public class Foo1 : IFoo { }
public class Foo2 : IFoo { }
public class Foo3 : IFoo { }
[Test(Description = "Exercises a problem in a previous version, to make sure older Autofac.dll isn't picked up")]
public void EnumerablesFromDifferentLifetimeScopesShouldReturnDifferentCollections() {
var rootBuilder = new ContainerBuilder();
rootBuilder.RegisterType<Foo1>().As<IFoo>();
var rootContainer = rootBuilder.Build();
var scopeA = rootContainer.BeginLifetimeScope(
scopeBuilder => scopeBuilder.RegisterType<Foo2>().As<IFoo>());
var arrayA = scopeA.Resolve<IEnumerable<IFoo>>().ToArray();
var scopeB = rootContainer.BeginLifetimeScope(
scopeBuilder => scopeBuilder.RegisterType<Foo3>().As<IFoo>());
var arrayB = scopeB.Resolve<IEnumerable<IFoo>>().ToArray();
Assert.That(arrayA.Count(), Is.EqualTo(2));
Assert.That(arrayA, Has.Some.TypeOf<Foo1>());
Assert.That(arrayA, Has.Some.TypeOf<Foo2>());
Assert.That(arrayB.Count(), Is.EqualTo(2));
Assert.That(arrayB, Has.Some.TypeOf<Foo1>());
Assert.That(arrayB, Has.Some.TypeOf<Foo3>());
}
}
}

View File

@@ -263,7 +263,7 @@ namespace Orchard.Tests.Environment {
[Test]
public void DataPrefixChangesTableName() {
var settings = BuildDefaultSettings();
settings.DataPrefix = "Yadda";
settings.DataTablePrefix = "Yadda";
var descriptor = Build.TopologyDescriptor().WithFeatures("Foo Plus", "Bar", "Bar Minus");
_extensionDescriptors = new[] {

View File

@@ -0,0 +1,166 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using Orchard.Environment;
using Orchard.Environment.Configuration;
using Orchard.Tests.Stubs;
namespace Orchard.Tests.Environment {
[TestFixture]
public class RunningShellTableTests {
[Test]
public void NoShellsGiveNoMatch() {
var table = new RunningShellTable();
var match = table.Match(new StubHttpContext());
Assert.That(match, Is.Null);
}
[Test]
public void DefaultShellMatchesByDefault() {
var table = (IRunningShellTable)new RunningShellTable();
var settings = new ShellSettings { Name = "Default" };
table.Add(settings);
var match = table.Match(new StubHttpContext());
Assert.That(match, Is.SameAs(settings));
}
[Test]
public void AnotherShellMatchesByHostHeader() {
var table = (IRunningShellTable)new RunningShellTable();
var settings = new ShellSettings { Name = "Default" };
var settingsA = new ShellSettings { Name = "Alpha", RequestUrlHost = "a.example.com" };
table.Add(settings);
table.Add(settingsA);
var match = table.Match(new StubHttpContext("~/foo/bar", "a.example.com"));
Assert.That(match, Is.SameAs(settingsA));
}
[Test]
public void DefaultStillCatchesWhenOtherShellsMiss() {
var table = (IRunningShellTable)new RunningShellTable();
var settings = new ShellSettings { Name = "Default" };
var settingsA = new ShellSettings { Name = "Alpha", RequestUrlHost = "a.example.com" };
table.Add(settings);
table.Add(settingsA);
var match = table.Match(new StubHttpContext("~/foo/bar", "b.example.com"));
Assert.That(match, Is.SameAs(settings));
}
[Test]
public void DefaultWontFallbackIfItHasCriteria() {
var table = (IRunningShellTable)new RunningShellTable();
var settings = new ShellSettings { Name = "Default", RequestUrlHost = "www.example.com" };
var settingsA = new ShellSettings { Name = "Alpha", RequestUrlHost = "a.example.com" };
table.Add(settings);
table.Add(settingsA);
var match = table.Match(new StubHttpContext("~/foo/bar", "b.example.com"));
Assert.That(match, Is.Null);
}
[Test]
public void DefaultWillCatchRequestsIfItMatchesCriteria() {
var table = (IRunningShellTable)new RunningShellTable();
var settings = new ShellSettings { Name = "Default", RequestUrlHost = "www.example.com" };
var settingsA = new ShellSettings { Name = "Alpha", RequestUrlHost = "a.example.com" };
table.Add(settings);
table.Add(settingsA);
var match = table.Match(new StubHttpContext("~/foo/bar", "www.example.com"));
Assert.That(match, Is.EqualTo(settings));
}
[Test]
public void NonDefaultCatchallWillFallbackIfNothingElseMatches() {
var table = (IRunningShellTable)new RunningShellTable();
var settings = new ShellSettings { Name = "Default", RequestUrlHost = "www.example.com" };
var settingsA = new ShellSettings { Name = "Alpha" };
table.Add(settings);
table.Add(settingsA);
var match = table.Match(new StubHttpContext("~/foo/bar", "b.example.com"));
Assert.That(match, Is.EqualTo(settingsA));
}
[Test]
public void DefaultCatchallIsFallbackEvenWhenOthersAreUnqualified() {
var table = (IRunningShellTable)new RunningShellTable();
var settings = new ShellSettings { Name = "Default" };
var settingsA = new ShellSettings { Name = "Alpha" };
var settingsB = new ShellSettings { Name = "Beta", RequestUrlHost = "b.example.com" };
var settingsG = new ShellSettings { Name = "Gamma" };
table.Add(settings);
table.Add(settingsA);
table.Add(settingsB);
table.Add(settingsG);
var match = table.Match(new StubHttpContext("~/foo/bar", "a.example.com"));
Assert.That(match, Is.EqualTo(settings));
}
[Test]
public void ThereIsNoFallbackIfMultipleSitesAreUnqualifiedButDefaultIsNotOneOfThem() {
var table = (IRunningShellTable)new RunningShellTable();
var settings = new ShellSettings { Name = "Default", RequestUrlHost = "www.example.com" };
var settingsA = new ShellSettings { Name = "Alpha" };
var settingsB = new ShellSettings { Name = "Beta", RequestUrlHost = "b.example.com" };
var settingsG = new ShellSettings { Name = "Gamma" };
table.Add(settings);
table.Add(settingsA);
table.Add(settingsB);
table.Add(settingsG);
var match = table.Match(new StubHttpContext("~/foo/bar", "a.example.com"));
Assert.That(match, Is.Null);
}
[Test]
public void PathAlsoCausesMatch() {
var table = (IRunningShellTable)new RunningShellTable();
var settings = new ShellSettings { Name = "Default" };
var settingsA = new ShellSettings { Name = "Alpha", RequestUrlPrefix = "~/foo" };
table.Add(settings);
table.Add(settingsA);
var match = table.Match(new StubHttpContext("~/foo/bar", "a.example.com"));
Assert.That(match, Is.SameAs(settingsA));
}
[Test]
public void PathAndHostMustBothMatch() {
var table = (IRunningShellTable)new RunningShellTable();
var settings = new ShellSettings { Name = "Default", RequestUrlHost = "www.example.com", };
var settingsA = new ShellSettings { Name = "Alpha", RequestUrlHost = "wiki.example.com", RequestUrlPrefix = "~/foo" };
var settingsB = new ShellSettings { Name = "Beta", RequestUrlHost = "wiki.example.com", RequestUrlPrefix = "~/bar" };
var settingsG = new ShellSettings { Name = "Gamma", RequestUrlHost = "wiki.example.com" };
var settingsD = new ShellSettings { Name = "Delta", RequestUrlPrefix = "~/Quux" };
table.Add(settings);
table.Add(settingsA);
table.Add(settingsB);
table.Add(settingsG);
table.Add(settingsD);
Assert.That(table.Match(new StubHttpContext("~/foo/bar", "wiki.example.com")), Is.SameAs(settingsA));
Assert.That(table.Match(new StubHttpContext("~/bar/foo", "wiki.example.com")), Is.SameAs(settingsB));
Assert.That(table.Match(new StubHttpContext("~/baaz", "wiki.example.com")), Is.SameAs(settingsG));
Assert.That(table.Match(new StubHttpContext("~/foo/bar", "www.example.com")), Is.SameAs(settings));
Assert.That(table.Match(new StubHttpContext("~/bar/foo", "www.example.com")), Is.SameAs(settings));
Assert.That(table.Match(new StubHttpContext("~/baaz", "www.example.com")), Is.SameAs(settings));
Assert.That(table.Match(new StubHttpContext("~/foo/bar", "a.example.com")), Is.Null);
Assert.That(table.Match(new StubHttpContext("~/quux/quad", "wiki.example.com")), Is.SameAs(settingsG));
Assert.That(table.Match(new StubHttpContext("~/quux/quad", "www.example.com")), Is.SameAs(settings));
Assert.That(table.Match(new StubHttpContext("~/quux/quad", "a.example.com")), Is.SameAs(settingsD));
Assert.That(table.Match(new StubHttpContext("~/yarg", "wiki.example.com")), Is.SameAs(settingsG));
Assert.That(table.Match(new StubHttpContext("~/yarg", "www.example.com")), Is.SameAs(settings));
Assert.That(table.Match(new StubHttpContext("~/yarg", "a.example.com")), Is.Null);
}
[Test]
public void PathAloneWillMatch() {
var table = (IRunningShellTable)new RunningShellTable();
var settingsA = new ShellSettings { Name = "Alpha", RequestUrlPrefix = "~/foo" };
table.Add(settingsA);
Assert.That(table.Match(new StubHttpContext("~/foo/bar", "wiki.example.com")), Is.SameAs(settingsA));
Assert.That(table.Match(new StubHttpContext("~/bar/foo", "wiki.example.com")), Is.Null);
}
}
}

View File

@@ -3,91 +3,95 @@ using System.Linq;
using System.Threading;
using System.Web.Mvc;
using System.Web.Routing;
using Autofac;
using NUnit.Framework;
using Orchard.Environment.Configuration;
using Orchard.Mvc.Routes;
using Orchard.Tests.Stubs;
using Orchard.Tests.Utility;
namespace Orchard.Tests.Mvc {
[TestFixture]
public class RouteCollectionPublisherTests {
private IContainer _container;
private RouteCollection _routes;
static RouteDescriptor Desc(string name, string url) {
return new RouteDescriptor {Name = name, Route = new Route(url, new MvcRouteHandler())};
return new RouteDescriptor { Name = name, Route = new Route(url, new MvcRouteHandler()) };
}
[SetUp]
public void Init() {
_routes = new RouteCollection();
var builder = new ContainerBuilder();
builder.RegisterType<RoutePublisher>().As<IRoutePublisher>();
builder.RegisterType<ShellRoute>().InstancePerDependency();
builder.Register(ctx => _routes);
builder.Register(ctx => new ShellSettings { Name = "Default" });
builder.RegisterAutoMocking();
_container = builder.Build();
}
[Test]
public void PublisherShouldReplaceRoutes() {
public void PublisherShouldAddRoutesThenReplaceTheOnesWhichWereAdded() {
_routes.MapRoute("foo", "{controller}");
var routes = new RouteCollection();
routes.MapRoute("foo", "{controller}");
var publisher = _container.Resolve<IRoutePublisher>();
publisher.Publish(new[] { Desc("barname", "bar"), Desc("quuxname", "quux") });
IRoutePublisher publisher = new RoutePublisher(routes, new StubContainerProvider(null, null));
publisher.Publish(new[] {Desc("barname", "bar"), Desc("quuxname", "quux")});
Assert.That(_routes.Count(), Is.EqualTo(3));
Assert.That(routes.Count(), Is.EqualTo(2));
publisher.Publish(new[] { Desc("baazname", "baaz")});
Assert.That(_routes.Count(), Is.EqualTo(2));
}
[Test]
public void RoutesCanHaveNullOrEmptyNames() {
var routes = new RouteCollection();
routes.MapRoute("foo", "{controller}");
_routes.MapRoute("foo", "{controller}");
IRoutePublisher publisher = new RoutePublisher(routes, new StubContainerProvider(null, null));
var publisher = _container.Resolve<IRoutePublisher>();
publisher.Publish(new[] { Desc(null, "bar"), Desc(string.Empty, "quux") });
Assert.That(routes.Count(), Is.EqualTo(2));
Assert.That(_routes.Count(), Is.EqualTo(3));
}
[Test]
[ExpectedException(typeof(ArgumentException))]
public void SameNameTwiceCausesExplosion() {
var routes = new RouteCollection();
routes.MapRoute("foo", "{controller}");
_routes.MapRoute("foo", "{controller}");
IRoutePublisher publisher = new RoutePublisher(routes, new StubContainerProvider(null, null));
publisher.Publish(new[] {Desc("yarg", "bar"), Desc("yarg", "quux")});
var publisher = _container.Resolve<IRoutePublisher>();
publisher.Publish(new[] { Desc("yarg", "bar"), Desc("yarg", "quux") });
Assert.That(routes.Count(), Is.EqualTo(2));
Assert.That(_routes.Count(), Is.EqualTo(2));
}
[Test]
public void ExplosionLeavesOriginalRoutesIntact() {
var routes = new RouteCollection();
routes.MapRoute("foo", "{controller}");
_routes.MapRoute("foo", "{controller}");
IRoutePublisher publisher = new RoutePublisher(routes, new StubContainerProvider(null, null));
var publisher = _container.Resolve<IRoutePublisher>();
try {
publisher.Publish(new[] { Desc("yarg", "bar"), Desc("yarg", "quux") });
}
catch (ArgumentException) {
Assert.That(routes.Count(), Is.EqualTo(1));
Assert.That(routes.OfType<Route>().Single().Url, Is.EqualTo("{controller}"));
Assert.That(_routes.Count(), Is.EqualTo(1));
Assert.That(_routes.OfType<Route>().Single().Url, Is.EqualTo("{controller}"));
}
}
[Test]
public void RoutesArePaintedWithConainerProviderAsTheyAreApplied() {
var routes = new RouteCollection();
routes.MapRoute("foo", "{controller}");
var containerProvider = new StubContainerProvider(null, null);
IRoutePublisher publisher = new RoutePublisher(routes, containerProvider);
publisher.Publish(new[] { Desc("barname", "bar"), Desc("quuxname", "quux") });
Assert.That(routes.OfType<Route>().Count(), Is.EqualTo(2));
Assert.That(routes.OfType<Route>().SelectMany(r => r.DataTokens.Values).Count(), Is.EqualTo(2));
Assert.That(routes.OfType<Route>().SelectMany(r => r.DataTokens.Values), Has.All.SameAs(containerProvider));
}
[Test]
public void WriteBlocksWhileReadIsInEffect() {
var routes = new RouteCollection();
routes.MapRoute("foo", "{controller}");
_routes.MapRoute("foo", "{controller}");
var containerProvider = new StubContainerProvider(null, null);
IRoutePublisher publisher = new RoutePublisher(routes, containerProvider);
var publisher = _container.Resolve<IRoutePublisher>();
var readLock = routes.GetReadLock();
var readLock = _routes.GetReadLock();
string where = "init";
var action = new Action(() => {
@@ -107,3 +111,4 @@ namespace Orchard.Tests.Mvc {
}
}
}

View File

@@ -0,0 +1,148 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using Autofac;
using Autofac.Integration.Web;
using NUnit.Framework;
using Orchard.Environment;
using Orchard.Environment.Configuration;
using Orchard.Mvc.Routes;
using Orchard.Tests.Stubs;
using Orchard.Tests.Utility;
namespace Orchard.Tests.Mvc.Routes {
[TestFixture]
public class ShellRouteTests {
private RouteCollection _routes;
private ILifetimeScope _containerA;
private ILifetimeScope _containerB;
private ShellSettings _settingsA;
private ShellSettings _settingsB;
private IContainer _rootContainer;
[SetUp]
public void Init() {
_settingsA = new ShellSettings { Name = "Alpha" };
_settingsB = new ShellSettings { Name = "Beta", };
_routes = new RouteCollection();
var rootBuilder = new ContainerBuilder();
rootBuilder.Register(ctx => _routes);
rootBuilder.RegisterType<ShellRoute>().InstancePerDependency();
rootBuilder.RegisterType<RunningShellTable>().As<IRunningShellTable>().SingleInstance();
_rootContainer = rootBuilder.Build();
_containerA = _rootContainer.BeginLifetimeScope(
builder => {
builder.Register(ctx => _settingsA);
builder.RegisterType<RoutePublisher>().As<IRoutePublisher>().InstancePerLifetimeScope();
});
_containerB = _rootContainer.BeginLifetimeScope(
builder => {
builder.Register(ctx => _settingsB);
builder.RegisterType<RoutePublisher>().As<IRoutePublisher>().InstancePerLifetimeScope();
});
}
[Test]
public void FactoryMethodWillCreateShellRoutes() {
var settings = new ShellSettings { Name = "Alpha" };
var builder = new ContainerBuilder();
builder.RegisterType<ShellRoute>().InstancePerDependency();
builder.RegisterAutoMocking();
builder.Register(ctx => settings);
var container = builder.Build();
var buildShellRoute = container.Resolve<Func<RouteBase, ShellRoute>>();
var routeA = new Route("foo", new MvcRouteHandler());
var route1 = buildShellRoute(routeA);
var routeB = new Route("bar", new MvcRouteHandler()) {
DataTokens = new RouteValueDictionary { { "area", "Beta" } }
};
var route2 = buildShellRoute(routeB);
Assert.That(route1, Is.Not.SameAs(route2));
Assert.That(route1.ShellSettingsName, Is.EqualTo("Alpha"));
Assert.That(route1.Area, Is.Null);
Assert.That(route2.ShellSettingsName, Is.EqualTo("Alpha"));
Assert.That(route2.Area, Is.EqualTo("Beta"));
}
[Test]
public void RoutePublisherReplacesOnlyNamedShellsRoutes() {
var routeA = new Route("foo", new MvcRouteHandler());
var routeB = new Route("bar", new MvcRouteHandler());
var routeC = new Route("quux", new MvcRouteHandler());
_containerA.Resolve<IRoutePublisher>().Publish(
new[] {new RouteDescriptor {Priority = 0, Route = routeA}});
_containerB.Resolve<IRoutePublisher>().Publish(
new[] {new RouteDescriptor {Priority = 0, Route = routeB}});
Assert.That(_routes.Count(), Is.EqualTo(2));
_containerA.Resolve<IRoutePublisher>().Publish(
new[] {new RouteDescriptor {Priority = 0, Route = routeC}});
Assert.That(_routes.Count(), Is.EqualTo(2));
_containerB.Resolve<IRoutePublisher>().Publish(
new[] {
new RouteDescriptor {Priority = 0, Route = routeA},
new RouteDescriptor {Priority = 0, Route = routeB},
});
Assert.That(_routes.Count(), Is.EqualTo(3));
}
[Test]
public void MatchingRouteToActiveShellTableWillLimitTheAbilityToMatchRoutes() {
var routeFoo = new Route("foo", new MvcRouteHandler());
_settingsA.RequestUrlHost = "a.example.com";
_containerA.Resolve<IRoutePublisher>().Publish(
new[] {new RouteDescriptor {Priority = 0, Route = routeFoo}});
_rootContainer.Resolve<IRunningShellTable>().Add(_settingsA);
_settingsB.RequestUrlHost = "b.example.com";
_containerB.Resolve<IRoutePublisher>().Publish(
new[] {new RouteDescriptor {Priority = 0, Route = routeFoo}});
_rootContainer.Resolve<IRunningShellTable>().Add(_settingsB);
var httpContext = new StubHttpContext("~/foo");
var routeData = _routes.GetRouteData(httpContext);
Assert.That(routeData, Is.Null);
var httpContextA = new StubHttpContext("~/foo", "a.example.com");
var routeDataA = _routes.GetRouteData(httpContextA);
Assert.That(routeDataA, Is.Not.Null);
Assert.That(routeDataA.DataTokens.ContainsKey("IContainerProvider"), Is.True);
var routeContainerProviderA = (IContainerProvider)routeDataA.DataTokens["IContainerProvider"];
Assert.That(routeContainerProviderA.ApplicationContainer.Resolve<IRoutePublisher>(), Is.SameAs(_containerA.Resolve<IRoutePublisher>()));
Assert.That(routeContainerProviderA.ApplicationContainer.Resolve<IRoutePublisher>(), Is.Not.SameAs(_containerB.Resolve<IRoutePublisher>()));
var httpContextB = new StubHttpContext("~/foo", "b.example.com");
var routeDataB = _routes.GetRouteData(httpContextB);
Assert.That(routeDataB, Is.Not.Null);
Assert.That(routeDataB.DataTokens.ContainsKey("IContainerProvider"), Is.True);
var routeContainerProviderB = (IContainerProvider)routeDataB.DataTokens["IContainerProvider"];
Assert.That(routeContainerProviderB.ApplicationContainer.Resolve<IRoutePublisher>(), Is.SameAs(_containerB.Resolve<IRoutePublisher>()));
Assert.That(routeContainerProviderB.ApplicationContainer.Resolve<IRoutePublisher>(), Is.Not.SameAs(_containerA.Resolve<IRoutePublisher>()));
}
}
}

View File

@@ -156,7 +156,9 @@
<Compile Include="Data\Builders\SessionFactoryBuilderTests.cs" />
<Compile Include="Data\RepositoryTests.cs" />
<Compile Include="Data\StubLocator.cs" />
<Compile Include="Environment\AutofacUtil\AutofacTests.cs" />
<Compile Include="Environment\AutofacUtil\DynamicProxy2\DynamicProxyTests.cs" />
<Compile Include="Environment\RunningShellTableTests.cs" />
<Compile Include="Environment\Utility\Build.cs" />
<Compile Include="Environment\Configuration\AppDataFolderTests.cs" />
<Compile Include="Environment\Configuration\DefaultTenantManagerTests.cs" />
@@ -166,6 +168,7 @@
<Compile Include="Environment\OrchardStarterTests.cs" />
<Compile Include="Environment\ShellBuilders\DefaultShellContainerFactoryTests.cs" />
<Compile Include="Environment\ShellBuilders\DefaultShellContextFactoryTests.cs" />
<Compile Include="Mvc\Routes\ShellRouteTests.cs" />
<Compile Include="Utility\ContainerExtensions.cs" />
<Compile Include="Environment\TestDependencies\TestDependency.cs" />
<Compile Include="Environment\Topology\DefaultShellDescriptorCacheTests.cs" />

View File

@@ -11,19 +11,6 @@ namespace Orchard.Tests.Services {
[TestFixture]
public class ClockTests {
[Test, Ignore("At the moment the default clock is using DateTime.Now until a user-time-zone corrected display is in effect.")]
public void DefaultClockShouldComeFromSystemUtc() {
IClock clock = new Clock();
var before = DateTime.UtcNow;
Thread.Sleep(2);
var mark = clock.UtcNow;
Thread.Sleep(2);
var after = DateTime.UtcNow;
Assert.That(mark.Kind, Is.EqualTo(DateTimeKind.Utc));
Assert.That(mark, Is.InRange(before, after));
}
[Test]
public void StubClockShouldComeFromSystemUtcAndDoesNotComeFromSystemTime() {
var clock = new StubClock();

View File

@@ -1,10 +1,12 @@
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Web;
namespace Orchard.Tests.Stubs {
public class StubHttpContext : HttpContextBase {
private readonly string _appRelativeCurrentExecutionFilePath;
private readonly string _hostHeader;
private readonly IDictionary _items = new Dictionary<object, object>();
public StubHttpContext() {
@@ -15,32 +17,46 @@ namespace Orchard.Tests.Stubs {
_appRelativeCurrentExecutionFilePath = appRelativeCurrentExecutionFilePath;
}
public StubHttpContext(string appRelativeCurrentExecutionFilePath, string hostHeader) {
_appRelativeCurrentExecutionFilePath = appRelativeCurrentExecutionFilePath;
_hostHeader = hostHeader;
}
public override HttpRequestBase Request {
get { return new StupHttpRequest(_appRelativeCurrentExecutionFilePath); }
get { return new StubHttpRequest(this); }
}
public override IDictionary Items {
get { return _items; }
}
public class StupHttpRequest : HttpRequestBase {
private readonly string _appRelativeCurrentExecutionFilePath;
class StubHttpRequest : HttpRequestBase {
private readonly StubHttpContext _httpContext;
private NameValueCollection _serverVariables;
public StupHttpRequest(string appRelativeCurrentExecutionFilePath) {
_appRelativeCurrentExecutionFilePath = appRelativeCurrentExecutionFilePath;
public StubHttpRequest(StubHttpContext httpContext) {
_httpContext = httpContext;
}
public override string AppRelativeCurrentExecutionFilePath {
get { return _appRelativeCurrentExecutionFilePath; }
get { return _httpContext._appRelativeCurrentExecutionFilePath; }
}
public override string ApplicationPath {
get { return "/"; }
get { return "/"; }
}
public override string PathInfo {
get { return ""; }
}
public override NameValueCollection ServerVariables {
get {
return _serverVariables = _serverVariables
?? new NameValueCollection { { "HTTP_HOST", _httpContext._hostHeader } };
}
}
}
}
}

View File

@@ -128,30 +128,12 @@
<Compile Include="Settings\Topology\Records\TopologyParameterRecord.cs" />
<Compile Include="Settings\Topology\Records\TopologyRecord.cs" />
<Compile Include="Settings\Topology\ShellDescriptorManager.cs" />
<Compile Include="Themes\DesignerNotes\ZoneManagerEvents.cs" />
<Compile Include="Themes\Preview\IPreviewTheme.cs" />
<Compile Include="Themes\Preview\PreviewThemeFilter.cs" />
<Compile Include="Themes\Preview\PreviewTheme.cs" />
<Compile Include="Themes\Services\SafeModeThemeSelector.cs" />
<Compile Include="Settings\AdminMenu.cs" />
<Compile Include="Settings\Controllers\AdminController.cs" />
<Compile Include="Settings\Handlers\SiteSettingsHandler.cs" />
<Compile Include="Settings\Models\SiteSettings.cs" />
<Compile Include="Settings\Services\SiteService.cs" />
<Compile Include="Settings\ViewModels\SettingsIndexViewModel.cs" />
<Compile Include="Themes\AdminMenu.cs" />
<Compile Include="Themes\Controllers\AdminController.cs" />
<Compile Include="Themes\Models\Theme.cs" />
<Compile Include="Themes\Models\ThemeSiteSettings.cs" />
<Compile Include="Themes\Handlers\ThemeSiteSettingsHandler.cs" />
<Compile Include="Themes\Permissions.cs" />
<Compile Include="Themes\Models\ThemeRecord.cs" />
<Compile Include="Themes\Models\ThemeSiteSettingsRecord.cs" />
<Compile Include="Themes\Services\SiteThemeSelector.cs" />
<Compile Include="Themes\Services\ThemeService.cs" />
<Compile Include="Themes\Services\ThemeZoneManagerEvents.cs" />
<Compile Include="Themes\ViewModels\PreviewViewModel.cs" />
<Compile Include="Themes\ViewModels\ThemesIndexViewModel.cs" />
<Compile Include="XmlRpc\Controllers\HomeController.cs" />
<Compile Include="XmlRpc\Controllers\LiveWriterController.cs" />
<Compile Include="XmlRpc\IXmlRpcHandler.cs" />
@@ -187,8 +169,6 @@
</ItemGroup>
<ItemGroup>
<Content Include="Common\Views\Web.config" />
<Content Include="Themes\Module.txt" />
<Content Include="Themes\Views\Admin\Index.aspx" />
</ItemGroup>
<ItemGroup>
<Content Include="Common\Scripts\jquery.slugify.js" />
@@ -200,16 +180,6 @@
<Content Include="Navigation\Module.txt" />
<Content Include="Scheduling\Module.txt" />
<Content Include="Settings\Views\EditorTemplates\Items\Settings.Site.ascx" />
<Content Include="Themes\Views\Admin\ThemePreview.ascx" />
<Content Include="Themes\Views\Admin\Install.aspx" />
<Content Include="Themes\Views\Header.ascx" />
<Content Include="Themes\Views\Document.aspx" />
<Content Include="Themes\Views\HeadPreload.ascx" />
<Content Include="Themes\Views\Layout.ascx" />
<Content Include="Themes\Views\Messages.ascx" />
<Content Include="Themes\Views\User.ascx" />
<Content Include="Themes\Views\Menu.ascx" />
<Content Include="Themes\Views\Web.config" />
</ItemGroup>
<ItemGroup>
<Content Include="Dashboard\Module.txt" />
@@ -218,10 +188,6 @@
<Content Include="Navigation\Views\Admin\Index.ascx" />
<Content Include="Navigation\Views\EditorTemplates\Parts\Navigation.EditMenuPart.ascx" />
<Content Include="Navigation\Views\Web.config" />
<Content Include="Themes\Scripts\jquery-1.4.1.js" />
<Content Include="Themes\Scripts\jquery-1.4.1.min.js" />
<Content Include="Themes\Views\EditorTemplates\Items\ContentItem.ascx" />
<Content Include="Themes\Views\DisplayTemplates\Items\ContentItem.ascx" />
</ItemGroup>
<ItemGroup>
<Content Include="Common\Views\DisplayTemplates\Parts\Common.Body.Summary.ascx" />
@@ -229,13 +195,6 @@
<Content Include="Common\Views\DisplayTemplates\Parts\Common.Body.ManageWrapperPre.ascx" />
<Content Include="Common\Views\DisplayTemplates\Parts\Common.Body.Manage.ascx" />
<Content Include="Dashboard\Views\Web.config" />
<Content Include="Themes\Styles\Images\toolBarActiveButtonBackground.gif" />
<Content Include="Themes\Styles\Images\toolBarBackground.gif" />
<Content Include="Themes\Styles\Images\toolBarHoverButtonBackground.gif" />
<Content Include="Themes\Content\orchard.ico" />
<Content Include="Themes\Scripts\base.js" />
<Content Include="Themes\Styles\special.css" />
<Content Include="Themes\Views\NotFound.ascx" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v9.0\WebApplications\Microsoft.WebApplication.targets" />

View File

@@ -3,6 +3,11 @@ using Orchard.Data.Conventions;
namespace Orchard.Core.Settings.Topology.Records {
public class TopologyRecord {
public TopologyRecord() {
EnabledFeatures=new List<TopologyFeatureRecord>();
Parameters=new List<TopologyParameterRecord>();
}
public virtual int Id { get; set; }
public virtual int SerialNumber { get; set; }

View File

@@ -62,33 +62,28 @@ namespace Orchard.Core.Settings.Topology {
throw new InvalidOperationException(T("Invalid serial number for shell topology").ToString());
if (topologyRecord == null) {
serialNumber++;
_topologyRecordRepository.Create(new TopologyRecord {
SerialNumber = serialNumber
});
topologyRecord = _topologyRecordRepository.Get(x => x.SerialNumber == serialNumber);
topologyRecord = new TopologyRecord {SerialNumber = 1};
_topologyRecordRepository.Create(topologyRecord);
}
else {
topologyRecord.SerialNumber++;
}
var descriptorFeatureRecords = new List<TopologyFeatureRecord>();
topologyRecord.EnabledFeatures.Clear();
foreach (var feature in enabledFeatures) {
descriptorFeatureRecords.Add(new TopologyFeatureRecord { Name = feature.Name, TopologyRecord = topologyRecord});
topologyRecord.EnabledFeatures.Add(new TopologyFeatureRecord { Name = feature.Name, TopologyRecord = topologyRecord });
}
topologyRecord.EnabledFeatures = descriptorFeatureRecords;
var descriptorParameterRecords = new List<TopologyParameterRecord>();
topologyRecord.Parameters.Clear();
foreach (var parameter in parameters) {
descriptorParameterRecords.Add(new TopologyParameterRecord {
topologyRecord.Parameters.Add(new TopologyParameterRecord {
Component = parameter.Component,
Name = parameter.Name,
Value = parameter.Value,
TopologyRecord = topologyRecord
});
}
topologyRecord.EnabledFeatures = descriptorFeatureRecords;
topologyRecord.Parameters = descriptorParameterRecords;
_eventBus.Notify(
typeof(IShellDescriptorManager).FullName + ".UpdateShellDescriptor",

View File

@@ -1,23 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
using Orchard.Mvc.ViewModels;
namespace Orchard.Core.Themes.ViewModels {
public class CreateThemeViewModel : AdminViewModel {
[Required]
public string Name { get; set; }
[Required]
public string Author { get; set; }
[Required]
public string Description { get; set; }
[Required]
public string Version { get; set; }
[Required]
public string Tags { get; set; }
[Required]
public string Homepage { get; set; }
}
}

View File

@@ -15,9 +15,8 @@ namespace Orchard.Web {
// Note: For instructions on enabling IIS6 or IIS7 classic mode,
// visit http://go.microsoft.com/?LinkId=9394801
public class MvcApplication : HttpApplication, IContainerProviderAccessor {
public class MvcApplication : HttpApplication {
private static IOrchardHost _host;
private static IContainerProvider _containerProvider;
public static void RegisterRoutes(RouteCollection routes) {
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
@@ -31,11 +30,6 @@ namespace Orchard.Web {
new Version("2.0.50129.0")/*MVC2 RC2 file version #*/,
new Version("2.0.41211.0")/*MVC2 RC file version #*/);
var builder = new ContainerBuilder();
builder.RegisterControllers(Assembly.GetExecutingAssembly());
_containerProvider = new ContainerProvider(builder.Build());
ControllerBuilder.Current.SetControllerFactory(new AutofacControllerFactory(ContainerProvider));
RegisterRoutes(RouteTable.Routes);
_host = OrchardStarter.CreateHost(MvcSingletons);
@@ -108,14 +102,5 @@ namespace Orchard.Web {
builder.RegisterInstance(ViewEngines.Engines);
}
#region Implementation of IContainerProviderAccessor
public IContainerProvider ContainerProvider {
get {
return _containerProvider;
}
}
#endregion
}
}

View File

@@ -198,9 +198,8 @@
<IISUrl>
</IISUrl>
<NTLMAuthentication>False</NTLMAuthentication>
<UseCustomServer>False</UseCustomServer>
<CustomServerUrl>
</CustomServerUrl>
<UseCustomServer>True</UseCustomServer>
<CustomServerUrl>http://orchard.codeplex.com</CustomServerUrl>
<SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
</WebProjectProperties>
</FlavorProperties>

View File

@@ -0,0 +1,14 @@
using Orchard.UI.Navigation;
namespace Orchard.Modules {
public class AdminMenu : INavigationProvider {
public string MenuName { get { return "admin"; } }
public void GetNavigation(NavigationBuilder builder) {
builder.Add("Modules", "10",
menu => menu
.Add("Manage Modules", "1.0", item => item.Action("Index", "Admin", new { area = "Orchard.Modules" })
.Permission(Permissions.ManageModules)));
}
}
}

View File

@@ -0,0 +1,17 @@
using System.Web.Mvc;
using Orchard.Modules.ViewModels;
namespace Orchard.Modules.Controllers {
public class AdminController : Controller {
private readonly IModuleService _moduleService;
public AdminController(IModuleService moduleService) {
_moduleService = moduleService;
}
public ActionResult Index() {
var modules = _moduleService.GetInstalledModules();
return View(new ModulesIndexViewModel {Modules = modules});
}
}
}

View File

@@ -0,0 +1,15 @@
using System.Collections.Generic;
using Orchard.Environment.Extensions.Models;
namespace Orchard.Modules.Models {
public class Module : IModule {
public string ModuleName { get; set; }
public string DisplayName { get; set; }
public string Description { get; set; }
public string Version { get; set; }
public string Author { get; set; }
public string HomePage { get; set; }
public string Tags { get; set; }
public IEnumerable<FeatureDescriptor> Features { get; set; }
}
}

View File

@@ -0,0 +1,2 @@
name: Modules
antiforgery: enabled

View File

@@ -0,0 +1,113 @@
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{17F86780-9A1F-4AA1-86F1-875EEC2730C7}</ProjectGuid>
<ProjectTypeGuids>{F85E285D-A4E0-4152-9332-AB1D724D3325};{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Orchard.Modules</RootNamespace>
<AssemblyName>Orchard.Modules</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<MvcBuildViews>false</MvcBuildViews>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.ComponentModel.DataAnnotations">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data.DataSetExtensions">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\lib\aspnetmvc\System.Web.Mvc.dll</HintPath>
</Reference>
<Reference Include="System.Xml.Linq">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Drawing" />
<Reference Include="System.Web" />
<Reference Include="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
<Reference Include="System.Web.Abstractions" />
<Reference Include="System.Web.Routing" />
<Reference Include="System.Xml" />
<Reference Include="System.Configuration" />
<Reference Include="System.Web.Services" />
<Reference Include="System.EnterpriseServices" />
<Reference Include="System.Web.Mobile" />
</ItemGroup>
<ItemGroup>
<Compile Include="AdminMenu.cs" />
<Compile Include="Controllers\AdminController.cs" />
<Compile Include="Models\Module.cs" />
<Compile Include="Permissions.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Services\ModuleService.cs" />
<Compile Include="ViewModels\ModulesIndexViewModel.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="Module.txt" />
<Content Include="Views\Admin\Index.ascx" />
<Content Include="Web.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\Orchard\Orchard.Framework.csproj">
<Project>{2D1D92BB-4555-4CBE-8D0E-63563D6CE4C6}</Project>
<Name>Orchard.Framework</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Content Include="Views\Web.config" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v9.0\WebApplications\Microsoft.WebApplication.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target> -->
<Target Name="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
<AspNetCompiler VirtualPath="temp" PhysicalPath="$(ProjectDir)" />
</Target>
<ProjectExtensions>
<VisualStudio>
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
<WebProjectProperties>
<UseIIS>False</UseIIS>
<AutoAssignPort>True</AutoAssignPort>
<DevelopmentServerPort>25046</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>
</IISUrl>
<NTLMAuthentication>False</NTLMAuthentication>
<UseCustomServer>True</UseCustomServer>
<CustomServerUrl>http://orchard.codeplex.com</CustomServerUrl>
<SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
</WebProjectProperties>
</FlavorProperties>
</VisualStudio>
</ProjectExtensions>
</Project>

View File

@@ -0,0 +1,25 @@
using System.Collections.Generic;
using Orchard.Security.Permissions;
namespace Orchard.Modules {
public class Permissions : IPermissionProvider {
public static readonly Permission ManageModules = new Permission { Description = "Manage Modules", Name = "ManageModules" };
public string ModuleName {
get { return "Modules"; }
}
public IEnumerable<Permission> GetPermissions() {
return new[] {ManageModules};
}
public IEnumerable<PermissionStereotype> GetDefaultStereotypes() {
return new[] {
new PermissionStereotype {
Name = "Administrator",
Permissions = new[] {ManageModules}
}
};
}
}
}

View File

@@ -0,0 +1,35 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Orchard.Modules")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Microsoft")]
[assembly: AssemblyProduct("Orchard.Modules")]
[assembly: AssemblyCopyright("Copyright © Microsoft 2010")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("9c778ece-c759-47fb-95b6-e73c03d9e969")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Orchard.Environment.Extensions;
using Orchard.Modules.Models;
namespace Orchard.Modules.Services {
public class ModuleService : IModuleService {
private readonly IExtensionManager _extensionManager;
public ModuleService(IExtensionManager extensionManager) {
_extensionManager = extensionManager;
}
public IModule GetModuleByName(string moduleName) {
return null;
}
public IEnumerable<IModule> GetInstalledModules() {
return
_extensionManager.AvailableExtensions().Where(
e => String.Equals(e.ExtensionType, "Module", StringComparison.OrdinalIgnoreCase)).Select(
descriptor => (new Module {
ModuleName = descriptor.Name,
DisplayName = descriptor.DisplayName,
Description = descriptor.Description,
Version = descriptor.Version,
Author = descriptor.Author,
HomePage = descriptor.WebSite,
Tags = descriptor.Tags
}) as IModule);
}
public void InstallModule(HttpPostedFileBase file) {
}
public void UninstallModule(string moduleName) {
}
}
}

View File

@@ -0,0 +1,8 @@
using System.Collections.Generic;
using Orchard.Mvc.ViewModels;
namespace Orchard.Modules.ViewModels {
public class ModulesIndexViewModel : BaseViewModel {
public IEnumerable<IModule> Modules { get; set; }
}
}

View File

@@ -0,0 +1,15 @@
<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl<ModulesIndexViewModel>" %>
<%@ Import Namespace="Orchard.Mvc.Html"%>
<%@ Import Namespace="Orchard.Modules.ViewModels"%>
<h1><%=Html.TitleForPage(T("Manage Modules").ToString()) %></h1>
<h2><%=T("Installed Modules") %></h2>
<% if (Model.Modules.Count() > 0) { %>
<ul><%
foreach (var module in Model.Modules.OrderBy(m => m.DisplayName)) { %>
<li>
<h3><%=Html.Encode(module.DisplayName) %></h3>
<p><%=module.Description != null ? Html.Encode(module.Description) : T("<em>no description</em>") %></p>
</li><%
} %>
</ul><%
} %>

View File

@@ -0,0 +1,34 @@
<?xml version="1.0"?>
<configuration>
<system.web>
<httpHandlers>
<add path="*" verb="*"
type="System.Web.HttpNotFoundHandler"/>
</httpHandlers>
<!--
Enabling request validation in view pages would cause validation to occur
after the input has already been processed by the controller. By default
MVC performs request validation before a controller processes the input.
To change this behavior apply the ValidateInputAttribute to a
controller or action.
-->
<pages
validateRequest="false"
pageParserFilterType="System.Web.Mvc.ViewTypeParserFilter, System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
pageBaseType="System.Web.Mvc.ViewPage, System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
userControlBaseType="System.Web.Mvc.ViewUserControl, System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<controls>
<add assembly="System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" namespace="System.Web.Mvc" tagPrefix="mvc" />
</controls>
</pages>
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
<handlers>
<remove name="BlockViewHandler"/>
<add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler"/>
</handlers>
</system.webServer>
</configuration>

View File

@@ -0,0 +1,140 @@
<?xml version="1.0"?>
<!--
Note: As an alternative to hand editing this file you can use the
web admin tool to configure settings for your application. Use
the Website->Asp.Net Configuration option in Visual Studio.
A full list of settings and comments can be found in
machine.config.comments usually located in
\Windows\Microsoft.Net\Framework\v2.x\Config
-->
<configuration>
<configSections>
<sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
<sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="Everywhere" />
<section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication" />
<section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication" />
<section name="roleService" type="System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication" />
</sectionGroup>
</sectionGroup>
</sectionGroup>
</configSections>
<appSettings/>
<connectionStrings>
<add name="ApplicationServices" connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true" providerName="System.Data.SqlClient"/>
</connectionStrings>
<system.web>
<!--
Set compilation debug="true" to insert debugging
symbols into the compiled page. Because this
affects performance, set this value to true only
during development.
-->
<compilation debug="false">
<assemblies>
<add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add assembly="System.Web.Abstractions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add assembly="System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add assembly="System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add assembly="System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<add assembly="System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<add assembly="System.Data.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
</assemblies>
</compilation>
<pages>
<controls>
<add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add tagPrefix="asp" namespace="System.Web.UI.WebControls" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
</controls>
<namespaces>
<add namespace="System.Web.Mvc"/>
<add namespace="System.Web.Mvc.Ajax"/>
<add namespace="System.Web.Mvc.Html"/>
<add namespace="System.Web.Routing"/>
<add namespace="System.Linq"/>
<add namespace="System.Collections.Generic"/>
</namespaces>
</pages>
<httpHandlers>
<remove verb="*" path="*.asmx"/>
<add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" validate="false"/>
</httpHandlers>
<httpModules>
<add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
</httpModules>
</system.web>
<system.codedom>
<compilers>
<compiler language="c#;cs;csharp" extension=".cs" warningLevel="4"
type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<providerOption name="CompilerVersion" value="v3.5"/>
<providerOption name="WarnAsError" value="false"/>
</compiler>
<compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" warningLevel="4"
type="Microsoft.VisualBasic.VBCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<providerOption name="CompilerVersion" value="v3.5"/>
<providerOption name="OptionInfer" value="true"/>
<providerOption name="WarnAsError" value="false"/>
</compiler>
</compilers>
</system.codedom>
<system.web.extensions/>
<!--
The system.webServer section is required for running ASP.NET AJAX under Internet
Information Services 7.0. It is not necessary for previous version of IIS.
-->
<system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
<modules runAllManagedModulesForAllRequests="true">
<remove name="ScriptModule" />
<remove name="UrlRoutingModule" />
<add name="ScriptModule" preCondition="managedHandler" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
</modules>
<handlers>
<remove name="WebServiceHandlerFactory-Integrated"/>
<remove name="ScriptHandlerFactory" />
<remove name="ScriptHandlerFactoryAppServices" />
<remove name="ScriptResource" />
<remove name="UrlRoutingHandler" />
<add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode"
type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode"
type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add name="ScriptResource" preCondition="integratedMode" verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add name="UrlRoutingHandler" preCondition="integratedMode" verb="*" path="UrlRouting.axd" type="System.Web.HttpForbiddenHandler, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</handlers>
</system.webServer>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35"/>
<bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View File

@@ -0,0 +1,14 @@
using Orchard.UI.Navigation;
namespace Orchard.MultiTenancy {
public class AdminMenu : INavigationProvider {
public string MenuName { get { return "admin"; } }
public void GetNavigation(NavigationBuilder builder) {
builder.Add("MultiTenancy", "2",
menu => menu
.Add("Manage Tenants", "1.0", item => item.Action("Index", "Admin", new { area = "Orchard.MultiTenancy" }).Permission(Permissions.ManageTenants))
.Add("Add New Tenant", "1.1", item => item.Action("Add", "Admin", new { area = "Orchard.MultiTenancy" }).Permission(Permissions.ManageTenants)));
}
}
}

View File

@@ -0,0 +1,75 @@
using System.Linq;
using Orchard.Commands;
using Orchard.Environment.Configuration;
using Orchard.MultiTenancy.Services;
namespace Orchard.MultiTenancy.Commands {
public class TenantCommand : DefaultOrchardCommandHandler {
private readonly ITenantService _tenantService;
public TenantCommand(ITenantService tenantService) {
_tenantService = tenantService;
}
[OrchardSwitch]
public string Host { get; set; }
[OrchardSwitch]
public string UrlPrefix { get; set; }
[CommandHelp("tenant list: Display current tenants of a site")]
[CommandName("tenant list")]
public void List() {
Context.Output.WriteLine(T("List of tenants"));
Context.Output.WriteLine(T("---------------------------"));
var tenants = _tenantService.GetTenants();
foreach (var tenant in tenants) {
Context.Output.WriteLine(T("Name: ") + tenant.Name);
Context.Output.WriteLine(T("Provider: ") + tenant.DataProvider);
Context.Output.WriteLine(T("ConnectionString: ") + tenant.DataConnectionString);
Context.Output.WriteLine(T("Data Table Prefix: ") + tenant.DataTablePrefix);
Context.Output.WriteLine(T("Request Url Host: ") + tenant.RequestUrlHost);
Context.Output.WriteLine(T("Request Url Prefix: ") + tenant.RequestUrlPrefix);
Context.Output.WriteLine(T("State: ") + tenant.State.ToString());
Context.Output.WriteLine(T("---------------------------"));
}
}
[CommandHelp("tenant add <tenantName> /Host:<hostname> /UrlPrefix:<url prefix>" +
": create new tenant named <tenantName> on the site")]
[CommandName("tenant add")]
public void Create(string tenantName) {
Context.Output.WriteLine(T("Creating tenant"));
_tenantService.CreateTenant(
new ShellSettings {
Name = tenantName,
RequestUrlHost = Host,
RequestUrlPrefix = UrlPrefix,
State = new TenantState("Uninitialized")
});
}
[CommandHelp("tenant info <tenantName>: Display settings for a tenant")]
[CommandName("tenant info")]
public void Info(string tenantName) {
ShellSettings tenant = _tenantService.GetTenants().Where(x => x.Name == tenantName).FirstOrDefault();
if (tenant == null) {
Context.Output.Write(T("Tenant: ") + tenantName + T(" was not found"));
}
else {
Context.Output.WriteLine(T("Tenant Settings:"));
Context.Output.WriteLine(T("---------------------------"));
Context.Output.WriteLine(T("Name: ") + tenant.Name);
Context.Output.WriteLine(T("Provider: ") + tenant.DataProvider);
Context.Output.WriteLine(T("ConnectionString: ") + tenant.DataConnectionString);
Context.Output.WriteLine(T("Data Table Prefix: ") + tenant.DataTablePrefix);
Context.Output.WriteLine(T("Request Url Host: ") + tenant.RequestUrlHost);
Context.Output.WriteLine(T("Request Url Prefix: ") + tenant.RequestUrlPrefix);
Context.Output.WriteLine(T("State: ") + tenant.State.ToString());
Context.Output.WriteLine(T("---------------------------"));
}
}
}
}

View File

@@ -0,0 +1,52 @@
using System;
using System.Web.Mvc;
using Orchard.Environment.Configuration;
using Orchard.Localization;
using Orchard.MultiTenancy.Services;
using Orchard.MultiTenancy.ViewModels;
using Orchard.UI.Notify;
namespace Orchard.MultiTenancy.Controllers {
[ValidateInput(false)]
public class AdminController : Controller {
private readonly ITenantService _tenantService;
public AdminController(ITenantService tenantService, IOrchardServices orchardServices) {
_tenantService = tenantService;
Services = orchardServices;
T = NullLocalizer.Instance;
}
private Localizer T { get; set; }
public IOrchardServices Services { get; set; }
public ActionResult Index() {
return View(new TenantsIndexViewModel { TenantSettings = _tenantService.GetTenants() });
}
public ActionResult Add() {
return View(new TenantsAddViewModel());
}
[HttpPost, ActionName("Add")]
public ActionResult AddPOST(TenantsAddViewModel viewModel) {
try {
if (!Services.Authorizer.Authorize(Permissions.ManageTenants, T("Couldn't create tenant")))
return new HttpUnauthorizedResult();
_tenantService.CreateTenant(
new ShellSettings {
Name = viewModel.Name,
RequestUrlHost = viewModel.RequestUrlHost,
RequestUrlPrefix = viewModel.RequestUrlPrefix,
State = new TenantState("Uninitialized")
});
return RedirectToAction("Index");
}
catch (Exception exception) {
Services.Notifier.Error(T("Creating Tenant failed: ") + exception.Message);
return View(viewModel);
}
}
}
}

View File

@@ -0,0 +1,2 @@
name: MultiTenancy
antiforgery: enabled

View File

@@ -0,0 +1,113 @@
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{72457126-E118-4171-A08F-9A709EE4B7FC}</ProjectGuid>
<ProjectTypeGuids>{F85E285D-A4E0-4152-9332-AB1D724D3325};{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Orchard.MultiTenancy</RootNamespace>
<AssemblyName>Orchard.MultiTenancy</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<MvcBuildViews>false</MvcBuildViews>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.ComponentModel.DataAnnotations">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data.DataSetExtensions">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\lib\aspnetmvc\System.Web.Mvc.dll</HintPath>
</Reference>
<Reference Include="System.Xml.Linq">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Web" />
<Reference Include="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
<Reference Include="System.Web.Abstractions" />
<Reference Include="System.Web.Routing" />
<Reference Include="System.Xml" />
<Reference Include="System.Configuration" />
<Reference Include="System.Web.Services" />
<Reference Include="System.EnterpriseServices" />
<Reference Include="System.Web.Mobile" />
</ItemGroup>
<ItemGroup>
<Compile Include="AdminMenu.cs" />
<Compile Include="Commands\TenantCommand.cs" />
<Compile Include="Controllers\AdminController.cs" />
<Compile Include="Services\ITenantService.cs" />
<Compile Include="Services\TenantService.cs" />
<Compile Include="ViewModels\TenantsAddViewModel.cs" />
<Compile Include="ViewModels\TenantsIndexViewModel.cs" />
<Compile Include="Permissions.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="Module.txt" />
<Content Include="Views\Admin\Add.ascx" />
<Content Include="Views\Admin\Index.ascx" />
<Content Include="Web.config" />
<Content Include="Views\Web.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\Orchard\Orchard.Framework.csproj">
<Project>{2D1D92BB-4555-4CBE-8D0E-63563D6CE4C6}</Project>
<Name>Orchard.Framework</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v9.0\WebApplications\Microsoft.WebApplication.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target> -->
<Target Name="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
<AspNetCompiler VirtualPath="temp" PhysicalPath="$(ProjectDir)" />
</Target>
<ProjectExtensions>
<VisualStudio>
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
<WebProjectProperties>
<UseIIS>False</UseIIS>
<AutoAssignPort>True</AutoAssignPort>
<DevelopmentServerPort>3803</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>
</IISUrl>
<NTLMAuthentication>False</NTLMAuthentication>
<UseCustomServer>True</UseCustomServer>
<CustomServerUrl>http://orchard.codeplex.com</CustomServerUrl>
<SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
</WebProjectProperties>
</FlavorProperties>
</VisualStudio>
</ProjectExtensions>
</Project>

View File

@@ -0,0 +1,30 @@
using System.Collections.Generic;
using Orchard.Security.Permissions;
namespace Orchard.MultiTenancy {
public class Permissions : IPermissionProvider {
public static readonly Permission ManageTenants = new Permission { Description = "Modifying Tenants of a Site", Name = "ManageTenants" };
public string ModuleName {
get {
return "MultiTenancy";
}
}
public IEnumerable<Permission> GetPermissions() {
return new[] {
ManageTenants
};
}
public IEnumerable<PermissionStereotype> GetDefaultStereotypes() {
return new[] {
new PermissionStereotype {
Name = "Administrator",
Permissions = new[] {ManageTenants}
},
};
}
}
}

View File

@@ -0,0 +1,35 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Orchard.MultiTenancy")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("MSIT")]
[assembly: AssemblyProduct("Orchard.MultiTenancy")]
[assembly: AssemblyCopyright("Copyright © MSIT 2010")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("f1ee1b86-72bb-45da-b8ee-b5465d4968ba")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,9 @@
using System.Collections.Generic;
using Orchard.Environment.Configuration;
namespace Orchard.MultiTenancy.Services {
public interface ITenantService : IDependency {
IEnumerable<ShellSettings> GetTenants();
void CreateTenant(ShellSettings settings);
}
}

View File

@@ -0,0 +1,24 @@
using System.Collections.Generic;
using Orchard.Environment.Configuration;
namespace Orchard.MultiTenancy.Services {
public class TenantService : ITenantService {
private readonly IShellSettingsManager _shellSettingsManager;
public TenantService(IShellSettingsManager shellSettingsManager) {
_shellSettingsManager = shellSettingsManager;
}
#region Implementation of ITenantService
public IEnumerable<ShellSettings> GetTenants() {
return _shellSettingsManager.LoadSettings();
}
public void CreateTenant(ShellSettings settings) {
_shellSettingsManager.SaveSettings(settings);
}
#endregion
}
}

View File

@@ -0,0 +1,13 @@
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using Orchard.Mvc.ViewModels;
namespace Orchard.MultiTenancy.ViewModels {
public class TenantsAddViewModel : BaseViewModel {
[Required, DisplayName("Tenant Name:")]
public string Name { get; set; }
public string RequestUrlHost { get; set; }
public string RequestUrlPrefix { get; set; }
}
}

View File

@@ -0,0 +1,9 @@
using System.Collections.Generic;
using Orchard.Environment.Configuration;
using Orchard.Mvc.ViewModels;
namespace Orchard.MultiTenancy.ViewModels {
public class TenantsIndexViewModel : BaseViewModel {
public IEnumerable<ShellSettings> TenantSettings { get; set; }
}
}

View File

@@ -0,0 +1,20 @@
<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl<TenantsAddViewModel>" %>
<%@ Import Namespace="Orchard.Mvc.Html"%>
<%@ Import Namespace="Orchard.MultiTenancy.ViewModels"%>
<h1><%=Html.TitleForPage(T("Add a Tenant to your Site").ToString()) %></h1>
<%using (Html.BeginFormAntiForgeryPost()) { %>
<%= Html.ValidationSummary() %>
<fieldset>
<label for="Name"><%=_Encoded("Tenant Name") %></label>
<input id="Name" class="textMedium" name="Name" type="text" /><br />
<label for="RequestUrlHost"><%=_Encoded("Host") %></label>
<input id="RequestUrlHost" class="textMedium" name="RequestUrlHost" type="text" /><br />
<label for="RequestUrlPrefix"><%=_Encoded("Url Prefix") %></label>
<input id="RequestUrlPrefix" class="textMedium" name="RequestUrlPrefix" type="text" /><br />
</fieldset>
<fieldset>
<input type="submit" class="button primaryAction" value="<%=_Encoded("Save") %>" />
</fieldset>
<% } %>

View File

@@ -0,0 +1,39 @@
<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl<TenantsIndexViewModel>" %>
<%@ Import Namespace="Orchard.Mvc.Html"%>
<%@ Import Namespace="Orchard.MultiTenancy.ViewModels"%>
<h1><%=Html.TitleForPage(T("List of Site's Tenants").ToString())%></h1>
<table class="items">
<colgroup>
<col id="Name" />
<col id="Data Provider" />
<col id="ConnectionString" />
<col id="TablePrefix" />
<col id="RequestUrlHost" />
<col id="RequestUrlPrefix" />
<col id="TenantState" />
</colgroup>
<thead>
<tr>
<td scope="col"><%=_Encoded("Name") %></td>
<td scope="col"><%=_Encoded("Data Provider") %></td>
<td scope="col"><%=_Encoded("ConnectionString") %></td>
<td scope="col"><%=_Encoded("Table Prefix") %></td>
<td scope="col"><%=_Encoded("Request Url Host") %></td>
<td scope="col"><%=_Encoded("Request Url Prefix") %></td>
<td scope="col"><%=_Encoded("State") %></td>
</tr>
</thead>
<tbody><%
foreach (var tenant in Model.TenantSettings) { %>
<tr>
<td><%= tenant.Name %></td>
<td><%= tenant.DataProvider %></td>
<td><%= tenant.DataConnectionString %></td>
<td><%= tenant.DataTablePrefix %></td>
<td><%= tenant.RequestUrlHost %></td>
<td><%= tenant.RequestUrlPrefix %></td>
<td><%= tenant.State %></td>
</tr><%
} %>
</tbody>
</table>

View File

@@ -0,0 +1,153 @@
<?xml version="1.0"?>
<!--
Note: As an alternative to hand editing this file you can use the
web admin tool to configure settings for your application. Use
the Website->Asp.Net Configuration option in Visual Studio.
A full list of settings and comments can be found in
machine.config.comments usually located in
\Windows\Microsoft.Net\Framework\v2.x\Config
-->
<configuration>
<configSections>
<sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
<sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="Everywhere" />
<section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication" />
<section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication" />
<section name="roleService" type="System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication" />
</sectionGroup>
</sectionGroup>
</sectionGroup>
</configSections>
<appSettings/>
<connectionStrings>
<add name="ApplicationServices" connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true" providerName="System.Data.SqlClient"/>
</connectionStrings>
<system.web>
<!--
Set compilation debug="true" to insert debugging
symbols into the compiled page. Because this
affects performance, set this value to true only
during development.
-->
<compilation debug="false">
<assemblies>
<add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add assembly="System.Web.Abstractions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add assembly="System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add assembly="System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add assembly="System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<add assembly="System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<add assembly="System.Data.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
</assemblies>
</compilation>
<!--
The <customErrors> section enables configuration
of what to do if/when an unhandled error occurs
during the execution of a request. Specifically,
it enables developers to configure html error pages
to be displayed in place of a error stack trace.
<customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">
<error statusCode="403" redirect="NoAccess.htm" />
<error statusCode="404" redirect="FileNotFound.htm" />
</customErrors>
-->
<pages>
<controls>
<add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add tagPrefix="asp" namespace="System.Web.UI.WebControls" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
</controls>
<namespaces>
<add namespace="System.Web.Mvc"/>
<add namespace="System.Web.Mvc.Ajax"/>
<add namespace="System.Web.Mvc.Html"/>
<add namespace="System.Web.Routing"/>
<add namespace="System.Linq"/>
<add namespace="System.Collections.Generic"/>
</namespaces>
</pages>
<httpHandlers>
<remove verb="*" path="*.asmx"/>
<add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" validate="false"/>
</httpHandlers>
<httpModules>
<add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
</httpModules>
</system.web>
<system.codedom>
<compilers>
<compiler language="c#;cs;csharp" extension=".cs" warningLevel="4"
type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<providerOption name="CompilerVersion" value="v3.5"/>
<providerOption name="WarnAsError" value="false"/>
</compiler>
<compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" warningLevel="4"
type="Microsoft.VisualBasic.VBCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<providerOption name="CompilerVersion" value="v3.5"/>
<providerOption name="OptionInfer" value="true"/>
<providerOption name="WarnAsError" value="false"/>
</compiler>
</compilers>
</system.codedom>
<system.web.extensions/>
<!--
The system.webServer section is required for running ASP.NET AJAX under Internet
Information Services 7.0. It is not necessary for previous version of IIS.
-->
<system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
<modules runAllManagedModulesForAllRequests="true">
<remove name="ScriptModule" />
<remove name="UrlRoutingModule" />
<add name="ScriptModule" preCondition="managedHandler" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
</modules>
<handlers>
<remove name="WebServiceHandlerFactory-Integrated"/>
<remove name="ScriptHandlerFactory" />
<remove name="ScriptHandlerFactoryAppServices" />
<remove name="ScriptResource" />
<remove name="UrlRoutingHandler" />
<add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode"
type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode"
type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add name="ScriptResource" preCondition="integratedMode" verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add name="UrlRoutingHandler" preCondition="integratedMode" verb="*" path="UrlRouting.axd" type="System.Web.HttpForbiddenHandler, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</handlers>
</system.webServer>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35"/>
<bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View File

@@ -81,9 +81,12 @@ namespace Orchard.Setup.Controllers {
DataConnectionString = model.DatabaseConnectionString
};
const string hardcoded = @"Orchard.Framework,
Common,Dashboard,Feeds,HomePage,Navigation,Scheduling,Settings,Themes,XmlRpc,
// The vanilla Orchard distibution has the following modules enabled.
const string hardcoded =
@"Orchard.Framework,
Common,Dashboard,Feeds,HomePage,Navigation,Scheduling,Settings,XmlRpc,
Orchard.Users,Orchard.Roles,TinyMce,
Orchard.Modules,Orchard.Themes,
Orchard.Pages,Orchard.Comments";
var shellDescriptor = new ShellDescriptor {
@@ -162,6 +165,7 @@ namespace Orchard.Setup.Controllers {
}
}
shellSettings.State = new TenantState("Running");
_shellSettingsManager.SaveSettings(shellSettings);
_orchardHost.Reinitialize_Obsolete();

View File

@@ -1,14 +1,14 @@
using Orchard.UI.Navigation;
namespace Orchard.Core.Themes {
namespace Orchard.Themes {
public class AdminMenu : INavigationProvider {
public string MenuName { get { return "admin"; } }
public void GetNavigation(NavigationBuilder builder) {
builder.Add("Site", "11",
menu => menu
.Add("Manage Themes", "4.0", item => item.Action("Index", "Admin", new { area = "Themes" })
.Permission(Permissions.ManageThemes).Permission(Permissions.ApplyTheme)));
.Add("Manage Themes", "4.0", item => item.Action("Index", "Admin", new { area = "Orchard.Themes" })
.Permission(Permissions.ManageThemes).Permission(Permissions.ApplyTheme)));
}
}
}
}

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -2,15 +2,14 @@
using System.Reflection;
using System.Web;
using System.Web.Mvc;
using Orchard.Core.Themes.Preview;
using Orchard.Core.Themes.ViewModels;
using Orchard.Localization;
using Orchard.Security;
using Orchard.Themes;
using Orchard.UI.Notify;
using Orchard.Mvc.ViewModels;
using Orchard.Security;
using Orchard.Themes.Preview;
using Orchard.Themes.ViewModels;
using Orchard.UI.Notify;
namespace Orchard.Core.Themes.Controllers {
namespace Orchard.Themes.Controllers {
[ValidateInput(false)]
public class AdminController : Controller {
private readonly IThemeService _themeService;
@@ -158,4 +157,4 @@ namespace Orchard.Core.Themes.Controllers {
}
}
}
}
}

View File

@@ -2,10 +2,9 @@
using System.Linq;
using System.Web.Mvc.Html;
using Orchard.Security;
using Orchard.Themes;
using Orchard.UI.Zones;
namespace Orchard.Core.Themes.DesignerNotes {
namespace Orchard.Themes.DesignerNotes {
public class ZoneManagerEvents : IZoneManagerEvents {
private readonly IThemeService _themeService;
private readonly IAuthorizationService _authorizationService;
@@ -35,12 +34,12 @@ namespace Orchard.Core.Themes.DesignerNotes {
if (accessAdminPanel) {
writer.Write("<div class=\"managewrapper\"><div class=\"manage\">");
writer.Write(context.Html.ActionLink("Edit", "AddWidget", new {
Area = "Futures.Widgets",
Controller = "Admin",
context.ZoneName,
theme.ThemeName,
ReturnUrl = requestContext.HttpContext.Request.Url,
}));
Area = "Futures.Widgets",
Controller = "Admin",
context.ZoneName,
theme.ThemeName,
ReturnUrl = requestContext.HttpContext.Request.Url,
}));
writer.Write("</div>");
}
writer.Write(File.ReadAllText(physicalPath));
@@ -58,4 +57,4 @@ namespace Orchard.Core.Themes.DesignerNotes {
public void ZoneRendered(ZoneRenderContext context) {
}
}
}
}

View File

@@ -1,9 +1,9 @@
using JetBrains.Annotations;
using Orchard.Core.Themes.Models;
using Orchard.Data;
using Orchard.ContentManagement.Handlers;
using Orchard.Themes.Models;
namespace Orchard.Core.Themes.Handlers {
namespace Orchard.Themes.Handlers {
[UsedImplicitly]
public class ThemeSiteSettingsHandler : ContentHandler {
public ThemeSiteSettingsHandler(IRepository<ThemeSiteSettingsRecord> repository) {

View File

@@ -1,7 +1,6 @@
using Orchard.ContentManagement;
using Orchard.Themes;
namespace Orchard.Core.Themes.Models {
namespace Orchard.Themes.Models {
public class Theme : ContentPart<ThemeRecord>, ITheme {
public static readonly ContentType ContentType = new ContentType { Name = "theme", DisplayName = "Themes" };

View File

@@ -1,6 +1,6 @@
using Orchard.ContentManagement.Records;
namespace Orchard.Core.Themes.Models {
namespace Orchard.Themes.Models {
public class ThemeRecord : ContentPartRecord {
public virtual string ThemeName { get; set; }
public virtual string DisplayName { get; set; }

View File

@@ -1,10 +1,10 @@
using Orchard.ContentManagement;
namespace Orchard.Core.Themes.Models {
namespace Orchard.Themes.Models {
public class ThemeSiteSettings : ContentPart<ThemeSiteSettingsRecord> {
public string CurrentThemeName {
get { return Record.CurrentThemeName; }
set { Record.CurrentThemeName = value; }
}
}
}
}

View File

@@ -1,6 +1,6 @@
using Orchard.ContentManagement.Records;
namespace Orchard.Core.Themes.Models {
namespace Orchard.Themes.Models {
public class ThemeSiteSettingsRecord : ContentPartRecord {
public virtual string CurrentThemeName { get; set; }
}

View File

@@ -0,0 +1,145 @@
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{CDE24A24-01D3-403C-84B9-37722E18DFB7}</ProjectGuid>
<ProjectTypeGuids>{F85E285D-A4E0-4152-9332-AB1D724D3325};{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Orchard.Themes</RootNamespace>
<AssemblyName>Orchard.Themes</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<MvcBuildViews>false</MvcBuildViews>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.ComponentModel.DataAnnotations">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data.DataSetExtensions">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\lib\aspnetmvc\System.Web.Mvc.dll</HintPath>
</Reference>
<Reference Include="System.Xml.Linq">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Drawing" />
<Reference Include="System.Web" />
<Reference Include="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
<Reference Include="System.Web.Abstractions" />
<Reference Include="System.Web.Routing" />
<Reference Include="System.Xml" />
<Reference Include="System.Configuration" />
<Reference Include="System.Web.Services" />
<Reference Include="System.EnterpriseServices" />
<Reference Include="System.Web.Mobile" />
</ItemGroup>
<ItemGroup>
<Compile Include="AdminMenu.cs" />
<Compile Include="Controllers\AdminController.cs" />
<Compile Include="DesignerNotes\ZoneManagerEvents.cs" />
<Compile Include="Handlers\ThemeSiteSettingsHandler.cs" />
<Compile Include="Models\Theme.cs" />
<Compile Include="Models\ThemeRecord.cs" />
<Compile Include="Models\ThemeSiteSettings.cs" />
<Compile Include="Models\ThemeSiteSettingsRecord.cs" />
<Compile Include="Permissions.cs" />
<Compile Include="Preview\IPreviewTheme.cs" />
<Compile Include="Preview\PreviewTheme.cs" />
<Compile Include="Preview\PreviewThemeFilter.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Services\SafeModeThemeSelector.cs" />
<Compile Include="Services\SiteThemeSelector.cs" />
<Compile Include="Services\ThemeService.cs" />
<Compile Include="Services\ThemeZoneManagerEvents.cs" />
<Compile Include="ViewModels\PreviewViewModel.cs" />
<Compile Include="ViewModels\ThemesIndexViewModel.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="Content\orchard.ico" />
<Content Include="Scripts\base.js" />
<Content Include="Scripts\jquery-1.4.1.js" />
<Content Include="Scripts\jquery-1.4.1.min.js" />
<Content Include="Styles\Images\toolBarActiveButtonBackground.gif" />
<Content Include="Styles\Images\toolBarBackground.gif" />
<Content Include="Styles\Images\toolBarHoverButtonBackground.gif" />
<Content Include="Styles\special.css" />
<Content Include="Views\Admin\Index.aspx" />
<Content Include="Views\Admin\Install.aspx" />
<Content Include="Views\Admin\ThemePreview.ascx" />
<Content Include="Views\DisplayTemplates\Items\ContentItem.ascx" />
<Content Include="Views\Document.aspx" />
<Content Include="Views\EditorTemplates\Items\ContentItem.ascx" />
<Content Include="Views\Header.ascx" />
<Content Include="Views\HeadPreload.ascx" />
<Content Include="Views\Layout.ascx" />
<Content Include="Views\Menu.ascx" />
<Content Include="Views\Messages.ascx" />
<Content Include="Views\NotFound.ascx" />
<Content Include="Views\User.ascx" />
<Content Include="Web.config" />
</ItemGroup>
<ItemGroup>
<Content Include="Module.txt" />
<Content Include="Views\Web.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\Orchard\Orchard.Framework.csproj">
<Project>{2D1D92BB-4555-4CBE-8D0E-63563D6CE4C6}</Project>
<Name>Orchard.Framework</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v9.0\WebApplications\Microsoft.WebApplication.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target> -->
<Target Name="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
<AspNetCompiler VirtualPath="temp" PhysicalPath="$(ProjectDir)" />
</Target>
<ProjectExtensions>
<VisualStudio>
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
<WebProjectProperties>
<UseIIS>False</UseIIS>
<AutoAssignPort>True</AutoAssignPort>
<DevelopmentServerPort>20578</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>
</IISUrl>
<NTLMAuthentication>False</NTLMAuthentication>
<UseCustomServer>True</UseCustomServer>
<CustomServerUrl>http://orchard.codeplex.com</CustomServerUrl>
<SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
</WebProjectProperties>
</FlavorProperties>
</VisualStudio>
</ProjectExtensions>
</Project>

View File

@@ -1,7 +1,7 @@
using System.Collections.Generic;
using Orchard.Security.Permissions;
namespace Orchard.Core.Themes {
namespace Orchard.Themes {
public class Permissions : IPermissionProvider {
public static readonly Permission ManageThemes = new Permission { Description = "Manage Themes", Name = "ManageThemes" };
public static readonly Permission ApplyTheme = new Permission { Description = "Apply a Theme", Name = "ApplyTheme" };
@@ -14,18 +14,18 @@ namespace Orchard.Core.Themes {
public IEnumerable<Permission> GetPermissions() {
return new Permission[] {
ManageThemes,
ApplyTheme,
};
ManageThemes,
ApplyTheme,
};
}
public IEnumerable<PermissionStereotype> GetDefaultStereotypes() {
return new[] {
new PermissionStereotype {
Name = "Administrator",
Permissions = new[] {ManageThemes, ApplyTheme}
},
};
new PermissionStereotype {
Name = "Administrator",
Permissions = new[] {ManageThemes, ApplyTheme}
},
};
}
}
}

View File

@@ -1,4 +1,4 @@
namespace Orchard.Core.Themes.Preview {
namespace Orchard.Themes.Preview {
public interface IPreviewTheme : IDependency {
string GetPreviewTheme();
void SetPreviewTheme(string themeName);

View File

@@ -1,9 +1,8 @@
using System;
using System.Web;
using System.Web.Routing;
using Orchard.Themes;
namespace Orchard.Core.Themes.Preview {
namespace Orchard.Themes.Preview {
public class PreviewTheme : IPreviewTheme, IThemeSelector {
private static readonly string PreviewThemeKey = typeof(PreviewTheme).FullName;
private readonly HttpContextBase _httpContext;

View File

@@ -1,11 +1,10 @@
using System.Linq;
using System.Web.Mvc;
using Orchard.Core.Themes.ViewModels;
using Orchard.Mvc.Filters;
using Orchard.Mvc.ViewModels;
using Orchard.Themes;
using Orchard.Themes.ViewModels;
namespace Orchard.Core.Themes.Preview {
namespace Orchard.Themes.Preview {
public class PreviewThemeFilter : FilterProvider, IResultFilter {
private readonly IThemeService _themeService;
private readonly IPreviewTheme _previewTheme;
@@ -26,12 +25,12 @@ namespace Orchard.Core.Themes.Preview {
var themes = _themeService.GetInstalledThemes();
var model = new PreviewViewModel {
Themes = themes.Select(theme => new SelectListItem {
Text = theme.DisplayName,
Value = theme.ThemeName,
Selected = theme.ThemeName == previewThemeName
})
};
Themes = themes.Select(theme => new SelectListItem {
Text = theme.DisplayName,
Value = theme.ThemeName,
Selected = theme.ThemeName == previewThemeName
})
};
baseViewModel.Zones.AddRenderPartial("body:before", "Admin/ThemePreview", model);
}
@@ -39,4 +38,4 @@ namespace Orchard.Core.Themes.Preview {
}
}
}
}

View File

@@ -0,0 +1,35 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Orchard.Themes")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Microsoft")]
[assembly: AssemblyProduct("Orchard.Themes")]
[assembly: AssemblyCopyright("Copyright © Microsoft 2010")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("3d727a0c-4b37-4081-bef6-68e68a3bae9b")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -1,8 +1,7 @@
using System.Web.Routing;
using JetBrains.Annotations;
using Orchard.Themes;
namespace Orchard.Core.Themes.Services {
namespace Orchard.Themes.Services {
[UsedImplicitly]
public class SafeModeThemeSelector : IThemeSelector {
public ThemeSelectorResult GetTheme(RequestContext context) {

View File

@@ -1,12 +1,11 @@
using System;
using System.Web.Routing;
using JetBrains.Annotations;
using Orchard.Core.Themes.Models;
using Orchard.ContentManagement;
using Orchard.Settings;
using Orchard.Themes;
using Orchard.Themes.Models;
namespace Orchard.Core.Themes.Services {
namespace Orchard.Themes.Services {
[UsedImplicitly]
public class SiteThemeSelector : IThemeSelector {
@@ -22,4 +21,4 @@ namespace Orchard.Core.Themes.Services {
return new ThemeSelectorResult { Priority = -5, ThemeName = currentThemeName };
}
}
}
}

View File

@@ -8,10 +8,9 @@ using Orchard.Environment.Extensions;
using Orchard.Logging;
using Orchard.ContentManagement;
using Orchard.Settings;
using Orchard.Themes;
using Orchard.Core.Themes.Models;
using Orchard.Themes.Models;
namespace Orchard.Core.Themes.Services {
namespace Orchard.Themes.Services {
[UsedImplicitly]
public class ThemeService : IThemeService {
private readonly IExtensionManager _extensionManager;
@@ -67,14 +66,14 @@ namespace Orchard.Core.Themes.Services {
foreach (var descriptor in _extensionManager.AvailableExtensions()) {
if (String.Equals(descriptor.Name, name, StringComparison.OrdinalIgnoreCase)) {
return new Theme {
Author = descriptor.Author ?? String.Empty,
Description = descriptor.Description ?? String.Empty,
DisplayName = descriptor.DisplayName ?? String.Empty,
HomePage = descriptor.WebSite ?? String.Empty,
ThemeName = descriptor.Name,
Version = descriptor.Version ?? String.Empty,
Tags = descriptor.Tags ?? String.Empty
};
Author = descriptor.Author ?? String.Empty,
Description = descriptor.Description ?? String.Empty,
DisplayName = descriptor.DisplayName ?? String.Empty,
HomePage = descriptor.WebSite ?? String.Empty,
ThemeName = descriptor.Name,
Version = descriptor.Version ?? String.Empty,
Tags = descriptor.Tags ?? String.Empty
};
}
}
return null;
@@ -85,14 +84,14 @@ namespace Orchard.Core.Themes.Services {
foreach (var descriptor in _extensionManager.AvailableExtensions()) {
if (String.Equals(descriptor.ExtensionType, "Theme", StringComparison.OrdinalIgnoreCase)) {
Theme theme = new Theme {
Author = descriptor.Author ?? String.Empty,
Description = descriptor.Description ?? String.Empty,
DisplayName = descriptor.DisplayName ?? String.Empty,
HomePage = descriptor.WebSite ?? String.Empty,
ThemeName = descriptor.Name,
Version = descriptor.Version ?? String.Empty,
Tags = descriptor.Tags ?? String.Empty
};
Author = descriptor.Author ?? String.Empty,
Description = descriptor.Description ?? String.Empty,
DisplayName = descriptor.DisplayName ?? String.Empty,
HomePage = descriptor.WebSite ?? String.Empty,
ThemeName = descriptor.Name,
Version = descriptor.Version ?? String.Empty,
Tags = descriptor.Tags ?? String.Empty
};
if (!theme.Tags.Contains("hidden")) {
themes.Add(theme);
}

View File

@@ -1,7 +1,7 @@
using Orchard.Localization;
using Orchard.UI.Zones;
namespace Orchard.Core.Themes.Services {
namespace Orchard.Themes.Services {
public class ThemeZoneManagerEvents : IZoneManagerEvents {
public ThemeZoneManagerEvents() {
T = NullLocalizer.Instance;

Some files were not shown because too many files have changed in this diff Show More