Merge dev -> perf

--HG--
branch : perf
This commit is contained in:
Suha Can
2010-12-03 11:34:33 -08:00
299 changed files with 3101 additions and 1360 deletions

View File

@@ -256,6 +256,10 @@
<Project>{D10AD48F-407D-4DB5-A328-173EC7CB010F}</Project>
<Name>Orchard.Roles</Name>
</ProjectReference>
<ProjectReference Include="..\..\Orchard.Web\Modules\Orchard.Scripting.Dlr\Orchard.Scripting.Dlr.csproj">
<Project>{2AD6973D-C7BB-416E-89FE-EEE34664E05F}</Project>
<Name>Orchard.Scripting.Dlr</Name>
</ProjectReference>
<ProjectReference Include="..\..\Orchard.Web\Modules\Orchard.Scripting\Orchard.Scripting.csproj">
<Project>{2AD6973D-C7BB-416E-89FE-EEE34664E05F}</Project>
<Name>Orchard.Scripting</Name>

View File

@@ -1,9 +1,5 @@
<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<!-- system.web>
<machineKey xdt:Transform="Remove" />
<machineKey xdt:Transform="Insert" validationKey="AutoGenerate" decryptionKey="AutoGenerate" validation="SHA1" decryption="AES" />
</system.web -->
<system.web.extensions xdt:Transform="Remove" />
</configuration>

View File

@@ -1,9 +1,5 @@
<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<!-- system.web>
<machineKey xdt:Transform="Remove" />
<machineKey xdt:Transform="Insert" validationKey="AutoGenerate" decryptionKey="AutoGenerate" validation="SHA1" decryption="AES" />
</system.web -->
<system.web.extensions xdt:Transform="Remove" />
</configuration>

View File

@@ -40,7 +40,6 @@
<defaultSettings timeout="00:30:00"/>
</system.transactions>
<system.web>
<machineKey validationKey="013B82F217ABB7EAB1F699E4E5B4D290030644D435994692354DAE82B06568B058BFE3C57BF199A41FFDBC84F3BC74D9C5BD96D1265F36A22D58347B591AC8DD" decryptionKey="04797035C490263D73ED991C84C5DFCD0D0206AD4F12BC3638A38FBEABEBB8C7" validation="SHA1" decryption="AES" />
<httpRuntime requestValidationMode="2.0" />
<!--

View File

@@ -77,7 +77,9 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Orchard.Pages", "..\Orchard
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Orchard.PublishLater", "..\Orchard.Web\Modules\Orchard.PublishLater\Orchard.PublishLater.csproj", "{C889167C-E52C-4A65-A419-224B3D1B957D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Orchard.Scripting", "..\Orchard.Web\Modules\Orchard.Scripting\Orchard.Scripting.csproj", "{2AD6973D-C7BB-416E-89FE-EEE34664E05F}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Orchard.Scripting", "..\Orchard.Web\Modules\Orchard.Scripting\Orchard.Scripting.csproj", "{99002B65-86F7-415E-BF4A-381AA8AB9CCC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Orchard.Scripting.Dlr", "..\Orchard.Web\Modules\Orchard.Scripting.Dlr\Orchard.Scripting.Dlr.csproj", "{2AD6973D-C7BB-416E-89FE-EEE34664E05F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -225,6 +227,10 @@ Global
{C889167C-E52C-4A65-A419-224B3D1B957D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C889167C-E52C-4A65-A419-224B3D1B957D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C889167C-E52C-4A65-A419-224B3D1B957D}.Release|Any CPU.Build.0 = Release|Any CPU
{99002B65-86F7-415E-BF4A-381AA8AB9CCC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{99002B65-86F7-415E-BF4A-381AA8AB9CCC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{99002B65-86F7-415E-BF4A-381AA8AB9CCC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{99002B65-86F7-415E-BF4A-381AA8AB9CCC}.Release|Any CPU.Build.0 = Release|Any CPU
{2AD6973D-C7BB-416E-89FE-EEE34664E05F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2AD6973D-C7BB-416E-89FE-EEE34664E05F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2AD6973D-C7BB-416E-89FE-EEE34664E05F}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -262,6 +268,7 @@ Global
{085948FF-0E9B-4A9A-B564-F8B8B4BDDDBC} = {8E3DE014-9B28-4B32-8AC1-B2BE404E9B2D}
{3420C92A-747F-4990-BA08-F2C9531E44AD} = {8E3DE014-9B28-4B32-8AC1-B2BE404E9B2D}
{C889167C-E52C-4A65-A419-224B3D1B957D} = {8E3DE014-9B28-4B32-8AC1-B2BE404E9B2D}
{99002B65-86F7-415E-BF4A-381AA8AB9CCC} = {8E3DE014-9B28-4B32-8AC1-B2BE404E9B2D}
{2AD6973D-C7BB-416E-89FE-EEE34664E05F} = {8E3DE014-9B28-4B32-8AC1-B2BE404E9B2D}
{33B1BC8D-E292-4972-A363-22056B207156} = {75E7476C-C05B-4C41-8E38-081D3EB55659}
{CB70A642-8CEC-4DDE-8C9F-AD08900EC98D} = {84650275-884D-4CBB-9CC0-67553996E211}

View File

@@ -2,6 +2,7 @@
using Orchard.Environment.Configuration;
using Orchard.Environment.Descriptor;
using Orchard.Environment.Descriptor.Models;
using Orchard.Environment.Extensions.Models;
using Orchard.Specs.Hosting.Orchard.Web;
using TechTalk.SpecFlow;
@@ -10,12 +11,19 @@ namespace Orchard.Specs.Bindings {
public class OrchardSiteFactory : BindingBase {
[Given(@"I have installed Orchard")]
public void GivenIHaveInstalledOrchard() {
GivenIHaveInstalledOrchard("/");
}
[Given(@"I have installed Orchard at ""(.*)\""")]
public void GivenIHaveInstalledOrchard(string virtualDirectory) {
var webApp = Binding<WebAppHosting>();
webApp.GivenIHaveACleanSiteWith(TableData(
new { extension = "module", names = "Orchard.Setup, Orchard.Pages, Orchard.Blogs, Orchard.Messaging, Orchard.Modules, Orchard.Packaging, Orchard.PublishLater, Orchard.Themes, Orchard.Scripting, Orchard.Widgets, Orchard.Users, Orchard.Roles, Orchard.Comments, Orchard.jQuery, Orchard.Tags, TinyMce" },
new { extension = "core", names = "Common, Dashboard, Feeds, HomePage, Navigation, Contents, Routable, Scheduling, Settings, Shapes, XmlRpc" },
new { extension = "theme", names = "SafeMode, TheAdmin, TheThemeMachine" }));
webApp.GivenIHaveACleanSiteWith(
virtualDirectory,
TableData(
new { extension = DefaultExtensionTypes.Module, names = "Orchard.Setup, Orchard.Pages, Orchard.Blogs, Orchard.Messaging, Orchard.Modules, Orchard.Packaging, Orchard.PublishLater, Orchard.Themes, Orchard.Scripting, Orchard.Widgets, Orchard.Users, Orchard.Roles, Orchard.Comments, Orchard.jQuery, Orchard.Tags, TinyMce" },
new { extension = DefaultExtensionTypes.Core, names = "Common, Dashboard, Feeds, HomePage, Navigation, Contents, Routable, Scheduling, Settings, Shapes, XmlRpc" },
new { extension = DefaultExtensionTypes.Theme, names = "SafeMode, TheAdmin, TheThemeMachine" }));
webApp.WhenIGoTo("Setup");

View File

@@ -7,6 +7,7 @@ using HtmlAgilityPack;
using log4net.Appender;
using log4net.Core;
using NUnit.Framework;
using Orchard.Environment.Extensions.Models;
using Orchard.Specs.Hosting;
using TechTalk.SpecFlow;
using Path = Bleroy.FluentPath.Path;
@@ -60,8 +61,8 @@ namespace Orchard.Specs.Bindings {
}
[Given(@"I have a clean site")]
public void GivenIHaveACleanSite() {
GivenIHaveACleanSiteBasedOn("Orchard.Web");
public void GivenIHaveACleanSite(string virtualDirectory = "/") {
GivenIHaveACleanSiteBasedOn("Orchard.Web", virtualDirectory);
}
[Given(@"I have chosen to deploy modules as source files only")]
@@ -71,8 +72,13 @@ namespace Orchard.Specs.Bindings {
[Given(@"I have a clean site based on (.*)")]
public void GivenIHaveACleanSiteBasedOn(string siteFolder) {
GivenIHaveACleanSiteBasedOn(siteFolder, "/");
}
[Given(@"I have a clean site based on (.*) at ""(.*)""")]
public void GivenIHaveACleanSiteBasedOn(string siteFolder, string virtualDirectory) {
_webHost = new WebHost(_orchardTemp);
Host.Initialize(siteFolder, "/");
Host.Initialize(siteFolder, virtualDirectory ?? "/");
var shuttle = new Shuttle();
Host.Execute(() => {
log4net.Config.BasicConfigurator.Configure(new CastleAppender());
@@ -125,17 +131,23 @@ namespace Orchard.Specs.Bindings {
[Given(@"I have a clean site with")]
public void GivenIHaveACleanSiteWith(Table table) {
GivenIHaveACleanSite();
GivenIHaveACleanSiteWith("/", table);
}
[Given(@"I have a clean site at ""(.*)"" with")]
public void GivenIHaveACleanSiteWith(string virtualDirectory, Table table) {
GivenIHaveACleanSite(virtualDirectory);
foreach (var row in table.Rows) {
foreach (var name in row["names"].Split(',').Select(x => x.Trim())) {
switch (row["extension"]) {
case "core":
case DefaultExtensionTypes.Core:
GivenIHaveCore(name);
break;
case "module":
case DefaultExtensionTypes.Module:
GivenIHaveModule(name);
break;
case "theme":
case DefaultExtensionTypes.Theme:
GivenIHaveTheme(name);
break;
default:
@@ -202,6 +214,23 @@ namespace Orchard.Specs.Bindings {
else if (radio.Attributes.Contains("checked"))
radio.Attributes.Remove("checked");
}
break;
case "checkbox":
if (string.Equals(row["value"], "true", StringComparison.OrdinalIgnoreCase)) {
input.Attributes.Add("checked", "checked");
}
else {
input.Attributes.Remove("checked");
}
var hiddenForCheckbox = inputs.Where(
x =>
x.GetAttributeValue("type", "") == "hidden" &&
x.GetAttributeValue("name", x.GetAttributeValue("id", "")) == r["name"]
).FirstOrDefault();
if (hiddenForCheckbox != null)
hiddenForCheckbox.Attributes.Add("value", row["value"]);
break;
default:
input.Attributes.Add("value", row["value"]);

View File

@@ -15,15 +15,18 @@ Scenario: I can create a new blog and blog post
| name | value |
| Routable.Title | My Blog |
And I hit "Save"
And I go to "my-blog"
Then I should see "<h1[^>]*>.*?My Blog.*?</h1>"
When I go to "admin/blogs/my-blog/posts/create"
And I go to "admin/blogs"
And I follow "My Blog"
And I follow "New Post"
And I fill in
| name | value |
| Routable.Title | My Post |
| Body.Text | Hi there. |
And I hit "Publish Now"
And I go to "my-blog/my-post"
And I go to "my-blog"
Then I should see "<h1[^>]*>.*?My Blog.*?</h1>"
And I should see "<h1[^>]*>.*?My Post.*?</h1>"
When I go to "my-blog/my-post"
Then I should see "<h1[^>]*>.*?My Post.*?</h1>"
And I should see "Hi there."
@@ -34,7 +37,9 @@ Scenario: I can create a new blog with multiple blog posts each with the same ti
| name | value |
| Routable.Title | My Blog |
And I hit "Save"
And I go to "admin/blogs/my-blog/posts/create"
And I go to "admin/blogs"
And I follow "My Blog"
And I follow "New Post"
And I fill in
| name | value |
| Routable.Title | My Post |
@@ -43,7 +48,9 @@ Scenario: I can create a new blog with multiple blog posts each with the same ti
And I go to "my-blog/my-post"
Then I should see "<h1[^>]*>.*?My Post.*?</h1>"
And I should see "Hi there."
When I go to "admin/blogs/my-blog/posts/create"
When I go to "admin/blogs"
And I follow "My Blog"
And I follow "New Post"
And I fill in
| name | value |
| Routable.Title | My Post |
@@ -52,7 +59,9 @@ Scenario: I can create a new blog with multiple blog posts each with the same ti
And I go to "my-blog/my-post-2"
Then I should see "<h1[^>]*>.*?My Post.*?</h1>"
And I should see "Hi there, again."
When I go to "admin/blogs/my-blog/posts/create"
When I go to "admin/blogs"
And I follow "My Blog"
And I follow "New Post"
And I fill in
| name | value |
| Routable.Title | My Post |
@@ -72,7 +81,9 @@ Scenario: I can create a new blog and blog post and when I change the slug of th
And I hit "Save"
And I go to "my-blog"
Then I should see "<h1[^>]*>.*?My Blog.*?</h1>"
When I go to "admin/blogs/my-blog/posts/create"
When I go to "admin/blogs"
And I follow "My Blog"
And I follow "New Post"
And I fill in
| name | value |
| Routable.Title | My Post |
@@ -81,7 +92,8 @@ Scenario: I can create a new blog and blog post and when I change the slug of th
And I go to "my-blog/my-post"
Then I should see "<h1[^>]*>.*?My Post.*?</h1>"
And I should see "Hi there."
When I go to "admin/blogs/my-blog"
When I go to "admin/blogs"
And I follow "My Blog"
And I follow "Blog Properties"
And I fill in
| name | value |
@@ -100,7 +112,9 @@ Scenario: When viewing a blog the user agent is given an RSS feed of the blog's
| name | value |
| Routable.Title | My Blog |
And I hit "Save"
And I go to "admin/blogs/my-blog/posts/create"
And I go to "admin/blogs"
And I follow "My Blog"
And I follow "New Post"
And I fill in
| name | value |
| Routable.Title | My Post |
@@ -125,4 +139,54 @@ Scenario: Enabling remote blog publishing inserts the appropriate metaweblogapi
When I go to "/XmlRpc/LiveWriter/Manifest"
Then the content type should be "\btext/xml\b"
And I should see "<manifest xmlns="http\://schemas\.microsoft\.com/wlw/manifest/weblog">"
And I should see "<clientType>Metaweblog</clientType>"
And I should see "<clientType>Metaweblog</clientType>"
Scenario: The virtual path of my installation when not at the root is reflected in the URL example for the slug field when creating a blog or blog post
Given I have installed Orchard at "/OrchardLocal"
When I go to "admin/blogs/create"
Then I should see "<span>http\://localhost/OrchardLocal/</span>"
When I fill in
| name | value |
| Routable.Title | My Blog |
And I hit "Save"
And I go to "admin/blogs"
And I follow "My Blog"
And I follow "New Post"
Then I should see "<span>http\://localhost/OrchardLocal/my-blog/</span>"
Scenario: The virtual path of my installation when at the root is reflected in the URL example for the slug field when creating a blog or blog post
Given I have installed Orchard at "/"
When I go to "admin/blogs/create"
Then I should see "<span>http\://localhost/</span>"
When I fill in
| name | value |
| Routable.Title | My Blog |
And I hit "Save"
And I go to "admin/blogs"
And I follow "My Blog"
And I follow "New Post"
Then I should see "<span>http\://localhost/my-blog/</span>"
Scenario: I set my blog to be the content for the home page and the posts for the blog be rooted to the app
Given I have installed Orchard
When I go to "admin/blogs/create"
And I fill in
| name | value |
| Routable.Title | My Blog |
| Routable.PromoteToHomePage | true |
And I hit "Save"
And I go to "admin/blogs"
And I follow "My Blog"
And I follow "New Post"
And I fill in
| name | value |
| Routable.Title | My Post |
| Body.Text | Hi there. |
And I hit "Publish Now"
And I am redirected
And I go to "/Default.aspx"
Then I should see "<h1>My Blog</h1>"
When I go to "/my-blog"
Then the status should be 404 "Not Found"
When I go to "/my-post"
Then I should see "<h1>My Post</h1>"

View File

@@ -1,7 +1,7 @@
// ------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by SpecFlow (http://www.specflow.org/).
// SpecFlow Version:1.3.2.0
// SpecFlow Version:1.4.0.0
// Runtime Version:4.0.30319.1
//
// Changes to this file may cause incorrect behavior and will be lost if
@@ -14,7 +14,7 @@ namespace Orchard.Specs
using TechTalk.SpecFlow;
[System.CodeDom.Compiler.GeneratedCodeAttribute("TechTalk.SpecFlow", "1.3.2.0")]
[System.CodeDom.Compiler.GeneratedCodeAttribute("TechTalk.SpecFlow", "1.4.0.0")]
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[NUnit.Framework.TestFixtureAttribute()]
[NUnit.Framework.DescriptionAttribute("Blog")]
@@ -31,7 +31,7 @@ namespace Orchard.Specs
{
testRunner = TechTalk.SpecFlow.TestRunnerManager.GetTestRunner();
TechTalk.SpecFlow.FeatureInfo featureInfo = new TechTalk.SpecFlow.FeatureInfo(new System.Globalization.CultureInfo("en-US"), "Blog", "In order to add blogs to my site\r\nAs an author\r\nI want to create blogs and create" +
", publish and edit blog posts", ((string[])(null)));
", publish and edit blog posts", GenerationTargetLanguage.CSharp, ((string[])(null)));
testRunner.OnFeatureStart(featureInfo);
}
@@ -61,11 +61,11 @@ namespace Orchard.Specs
#line 6
this.ScenarioSetup(scenarioInfo);
#line 7
testRunner.Given("I have installed Orchard");
testRunner.Given("I have installed Orchard");
#line 8
testRunner.When("I go to \"admin\"");
testRunner.When("I go to \"admin\"");
#line 9
testRunner.Then("I should see \"<a href=\"/Admin/Blogs/Create\">Blogs</a>\"");
testRunner.Then("I should see \"<a href=\"/Admin/Blogs/Create\">Blogs</a>\"");
#line hidden
testRunner.CollectScenarioErrors();
}
@@ -78,9 +78,9 @@ testRunner.Then("I should see \"<a href=\"/Admin/Blogs/Create\">Blogs</a>\"");
#line 11
this.ScenarioSetup(scenarioInfo);
#line 12
testRunner.Given("I have installed Orchard");
testRunner.Given("I have installed Orchard");
#line 13
testRunner.When("I go to \"admin/blogs/create\"");
testRunner.When("I go to \"admin/blogs/create\"");
#line hidden
TechTalk.SpecFlow.Table table1 = new TechTalk.SpecFlow.Table(new string[] {
"name",
@@ -89,15 +89,15 @@ testRunner.When("I go to \"admin/blogs/create\"");
"Routable.Title",
"My Blog"});
#line 14
testRunner.And("I fill in", ((string)(null)), table1);
testRunner.And("I fill in", ((string)(null)), table1);
#line 17
testRunner.And("I hit \"Save\"");
testRunner.And("I hit \"Save\"");
#line 18
testRunner.And("I go to \"my-blog\"");
testRunner.And("I go to \"admin/blogs\"");
#line 19
testRunner.Then("I should see \"<h1[^>]*>.*?My Blog.*?</h1>\"");
testRunner.And("I follow \"My Blog\"");
#line 20
testRunner.When("I go to \"admin/blogs/my-blog/posts/create\"");
testRunner.And("I follow \"New Post\"");
#line hidden
TechTalk.SpecFlow.Table table2 = new TechTalk.SpecFlow.Table(new string[] {
"name",
@@ -109,15 +109,21 @@ testRunner.When("I go to \"admin/blogs/my-blog/posts/create\"");
"Body.Text",
"Hi there."});
#line 21
testRunner.And("I fill in", ((string)(null)), table2);
testRunner.And("I fill in", ((string)(null)), table2);
#line 25
testRunner.And("I hit \"Publish Now\"");
testRunner.And("I hit \"Publish Now\"");
#line 26
testRunner.And("I go to \"my-blog/my-post\"");
testRunner.And("I go to \"my-blog\"");
#line 27
testRunner.Then("I should see \"<h1[^>]*>.*?My Post.*?</h1>\"");
testRunner.Then("I should see \"<h1[^>]*>.*?My Blog.*?</h1>\"");
#line 28
testRunner.And("I should see \"Hi there.\"");
testRunner.And("I should see \"<h1[^>]*>.*?My Post.*?</h1>\"");
#line 29
testRunner.When("I go to \"my-blog/my-post\"");
#line 30
testRunner.Then("I should see \"<h1[^>]*>.*?My Post.*?</h1>\"");
#line 31
testRunner.And("I should see \"Hi there.\"");
#line hidden
testRunner.CollectScenarioErrors();
}
@@ -129,12 +135,12 @@ testRunner.And("I should see \"Hi there.\"");
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("I can create a new blog with multiple blog posts each with the same title and uni" +
"que slugs are generated or given for said posts", ((string[])(null)));
#line 30
#line 33
this.ScenarioSetup(scenarioInfo);
#line 31
testRunner.Given("I have installed Orchard");
#line 32
testRunner.When("I go to \"admin/blogs/create\"");
#line 34
testRunner.Given("I have installed Orchard");
#line 35
testRunner.When("I go to \"admin/blogs/create\"");
#line hidden
TechTalk.SpecFlow.Table table3 = new TechTalk.SpecFlow.Table(new string[] {
"name",
@@ -142,12 +148,16 @@ testRunner.When("I go to \"admin/blogs/create\"");
table3.AddRow(new string[] {
"Routable.Title",
"My Blog"});
#line 33
testRunner.And("I fill in", ((string)(null)), table3);
#line 36
testRunner.And("I hit \"Save\"");
#line 37
testRunner.And("I go to \"admin/blogs/my-blog/posts/create\"");
testRunner.And("I fill in", ((string)(null)), table3);
#line 39
testRunner.And("I hit \"Save\"");
#line 40
testRunner.And("I go to \"admin/blogs\"");
#line 41
testRunner.And("I follow \"My Blog\"");
#line 42
testRunner.And("I follow \"New Post\"");
#line hidden
TechTalk.SpecFlow.Table table4 = new TechTalk.SpecFlow.Table(new string[] {
"name",
@@ -158,18 +168,22 @@ testRunner.And("I go to \"admin/blogs/my-blog/posts/create\"");
table4.AddRow(new string[] {
"Body.Text",
"Hi there."});
#line 38
testRunner.And("I fill in", ((string)(null)), table4);
#line 42
testRunner.And("I hit \"Publish Now\"");
#line 43
testRunner.And("I go to \"my-blog/my-post\"");
#line 44
testRunner.Then("I should see \"<h1[^>]*>.*?My Post.*?</h1>\"");
#line 45
testRunner.And("I should see \"Hi there.\"");
#line 46
testRunner.When("I go to \"admin/blogs/my-blog/posts/create\"");
testRunner.And("I fill in", ((string)(null)), table4);
#line 47
testRunner.And("I hit \"Publish Now\"");
#line 48
testRunner.And("I go to \"my-blog/my-post\"");
#line 49
testRunner.Then("I should see \"<h1[^>]*>.*?My Post.*?</h1>\"");
#line 50
testRunner.And("I should see \"Hi there.\"");
#line 51
testRunner.When("I go to \"admin/blogs\"");
#line 52
testRunner.And("I follow \"My Blog\"");
#line 53
testRunner.And("I follow \"New Post\"");
#line hidden
TechTalk.SpecFlow.Table table5 = new TechTalk.SpecFlow.Table(new string[] {
"name",
@@ -180,18 +194,22 @@ testRunner.When("I go to \"admin/blogs/my-blog/posts/create\"");
table5.AddRow(new string[] {
"Body.Text",
"Hi there, again."});
#line 47
testRunner.And("I fill in", ((string)(null)), table5);
#line 51
testRunner.And("I hit \"Publish Now\"");
#line 52
testRunner.And("I go to \"my-blog/my-post-2\"");
#line 53
testRunner.Then("I should see \"<h1[^>]*>.*?My Post.*?</h1>\"");
#line 54
testRunner.And("I should see \"Hi there, again.\"");
#line 55
testRunner.When("I go to \"admin/blogs/my-blog/posts/create\"");
testRunner.And("I fill in", ((string)(null)), table5);
#line 58
testRunner.And("I hit \"Publish Now\"");
#line 59
testRunner.And("I go to \"my-blog/my-post-2\"");
#line 60
testRunner.Then("I should see \"<h1[^>]*>.*?My Post.*?</h1>\"");
#line 61
testRunner.And("I should see \"Hi there, again.\"");
#line 62
testRunner.When("I go to \"admin/blogs\"");
#line 63
testRunner.And("I follow \"My Blog\"");
#line 64
testRunner.And("I follow \"New Post\"");
#line hidden
TechTalk.SpecFlow.Table table6 = new TechTalk.SpecFlow.Table(new string[] {
"name",
@@ -205,16 +223,16 @@ testRunner.When("I go to \"admin/blogs/my-blog/posts/create\"");
table6.AddRow(new string[] {
"Body.Text",
"Are you still there?"});
#line 56
testRunner.And("I fill in", ((string)(null)), table6);
#line 61
testRunner.And("I hit \"Publish Now\"");
#line 62
testRunner.And("I go to \"my-blog/my-post-3\"");
#line 63
testRunner.Then("I should see \"<h1[^>]*>.*?My Post.*?</h1>\"");
#line 64
testRunner.And("I should see \"Are you still there?\"");
#line 65
testRunner.And("I fill in", ((string)(null)), table6);
#line 70
testRunner.And("I hit \"Publish Now\"");
#line 71
testRunner.And("I go to \"my-blog/my-post-3\"");
#line 72
testRunner.Then("I should see \"<h1[^>]*>.*?My Post.*?</h1>\"");
#line 73
testRunner.And("I should see \"Are you still there?\"");
#line hidden
testRunner.CollectScenarioErrors();
}
@@ -226,12 +244,12 @@ testRunner.And("I should see \"Are you still there?\"");
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("I can create a new blog and blog post and when I change the slug of the blog the " +
"path of the plog post is updated", ((string[])(null)));
#line 66
#line 75
this.ScenarioSetup(scenarioInfo);
#line 67
testRunner.Given("I have installed Orchard");
#line 68
testRunner.When("I go to \"admin/blogs/create\"");
#line 76
testRunner.Given("I have installed Orchard");
#line 77
testRunner.When("I go to \"admin/blogs/create\"");
#line hidden
TechTalk.SpecFlow.Table table7 = new TechTalk.SpecFlow.Table(new string[] {
"name",
@@ -239,16 +257,20 @@ testRunner.When("I go to \"admin/blogs/create\"");
table7.AddRow(new string[] {
"Routable.Title",
"My Blog"});
#line 69
testRunner.And("I fill in", ((string)(null)), table7);
#line 72
testRunner.And("I hit \"Save\"");
#line 73
testRunner.And("I go to \"my-blog\"");
#line 74
testRunner.Then("I should see \"<h1[^>]*>.*?My Blog.*?</h1>\"");
#line 75
testRunner.When("I go to \"admin/blogs/my-blog/posts/create\"");
#line 78
testRunner.And("I fill in", ((string)(null)), table7);
#line 81
testRunner.And("I hit \"Save\"");
#line 82
testRunner.And("I go to \"my-blog\"");
#line 83
testRunner.Then("I should see \"<h1[^>]*>.*?My Blog.*?</h1>\"");
#line 84
testRunner.When("I go to \"admin/blogs\"");
#line 85
testRunner.And("I follow \"My Blog\"");
#line 86
testRunner.And("I follow \"New Post\"");
#line hidden
TechTalk.SpecFlow.Table table8 = new TechTalk.SpecFlow.Table(new string[] {
"name",
@@ -259,20 +281,22 @@ testRunner.When("I go to \"admin/blogs/my-blog/posts/create\"");
table8.AddRow(new string[] {
"Body.Text",
"Hi there."});
#line 76
testRunner.And("I fill in", ((string)(null)), table8);
#line 80
testRunner.And("I hit \"Publish Now\"");
#line 81
testRunner.And("I go to \"my-blog/my-post\"");
#line 82
testRunner.Then("I should see \"<h1[^>]*>.*?My Post.*?</h1>\"");
#line 83
testRunner.And("I should see \"Hi there.\"");
#line 84
testRunner.When("I go to \"admin/blogs/my-blog\"");
#line 85
testRunner.And("I follow \"Blog Properties\"");
#line 87
testRunner.And("I fill in", ((string)(null)), table8);
#line 91
testRunner.And("I hit \"Publish Now\"");
#line 92
testRunner.And("I go to \"my-blog/my-post\"");
#line 93
testRunner.Then("I should see \"<h1[^>]*>.*?My Post.*?</h1>\"");
#line 94
testRunner.And("I should see \"Hi there.\"");
#line 95
testRunner.When("I go to \"admin/blogs\"");
#line 96
testRunner.And("I follow \"My Blog\"");
#line 97
testRunner.And("I follow \"Blog Properties\"");
#line hidden
TechTalk.SpecFlow.Table table9 = new TechTalk.SpecFlow.Table(new string[] {
"name",
@@ -280,20 +304,20 @@ testRunner.And("I follow \"Blog Properties\"");
table9.AddRow(new string[] {
"Routable.Slug",
"my-other-blog"});
#line 86
testRunner.And("I fill in", ((string)(null)), table9);
#line 89
testRunner.And("I hit \"Save\"");
#line 90
testRunner.And("I go to \"my-other-blog\"");
#line 91
testRunner.Then("I should see \"<h1[^>]*>.*?My Blog.*?</h1>\"");
#line 92
testRunner.When("I go to \"my-other-blog/my-post\"");
#line 93
testRunner.Then("I should see \"<h1[^>]*>.*?My Post.*?</h1>\"");
#line 94
testRunner.And("I should see \"Hi there.\"");
#line 98
testRunner.And("I fill in", ((string)(null)), table9);
#line 101
testRunner.And("I hit \"Save\"");
#line 102
testRunner.And("I go to \"my-other-blog\"");
#line 103
testRunner.Then("I should see \"<h1[^>]*>.*?My Blog.*?</h1>\"");
#line 104
testRunner.When("I go to \"my-other-blog/my-post\"");
#line 105
testRunner.Then("I should see \"<h1[^>]*>.*?My Post.*?</h1>\"");
#line 106
testRunner.And("I should see \"Hi there.\"");
#line hidden
testRunner.CollectScenarioErrors();
}
@@ -303,12 +327,12 @@ testRunner.And("I should see \"Hi there.\"");
public virtual void WhenViewingABlogTheUserAgentIsGivenAnRSSFeedOfTheBlogSPosts()
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("When viewing a blog the user agent is given an RSS feed of the blog\'s posts", ((string[])(null)));
#line 96
#line 108
this.ScenarioSetup(scenarioInfo);
#line 97
testRunner.Given("I have installed Orchard");
#line 98
testRunner.When("I go to \"admin/blogs/create\"");
#line 109
testRunner.Given("I have installed Orchard");
#line 110
testRunner.When("I go to \"admin/blogs/create\"");
#line hidden
TechTalk.SpecFlow.Table table10 = new TechTalk.SpecFlow.Table(new string[] {
"name",
@@ -316,12 +340,16 @@ testRunner.When("I go to \"admin/blogs/create\"");
table10.AddRow(new string[] {
"Routable.Title",
"My Blog"});
#line 99
testRunner.And("I fill in", ((string)(null)), table10);
#line 102
testRunner.And("I hit \"Save\"");
#line 103
testRunner.And("I go to \"admin/blogs/my-blog/posts/create\"");
#line 111
testRunner.And("I fill in", ((string)(null)), table10);
#line 114
testRunner.And("I hit \"Save\"");
#line 115
testRunner.And("I go to \"admin/blogs\"");
#line 116
testRunner.And("I follow \"My Blog\"");
#line 117
testRunner.And("I follow \"New Post\"");
#line hidden
TechTalk.SpecFlow.Table table11 = new TechTalk.SpecFlow.Table(new string[] {
"name",
@@ -332,16 +360,16 @@ testRunner.And("I go to \"admin/blogs/my-blog/posts/create\"");
table11.AddRow(new string[] {
"Body.Text",
"Hi there."});
#line 104
testRunner.And("I fill in", ((string)(null)), table11);
#line 108
testRunner.And("I hit \"Publish Now\"");
#line 109
testRunner.And("I am redirected");
#line 110
testRunner.And("I go to \"my-blog/my-post\"");
#line 111
testRunner.Then("I should see \"<link rel=\"alternate\" type=\"application/rss\\+xml\" title=\"My Blog\" h" +
#line 118
testRunner.And("I fill in", ((string)(null)), table11);
#line 122
testRunner.And("I hit \"Publish Now\"");
#line 123
testRunner.And("I am redirected");
#line 124
testRunner.And("I go to \"my-blog/my-post\"");
#line 125
testRunner.Then("I should see \"<link rel=\"alternate\" type=\"application/rss\\+xml\" title=\"My Blog\" h" +
"ref=\"/rss\\?containerid=\\d+\" />\"");
#line hidden
testRunner.CollectScenarioErrors();
@@ -354,16 +382,16 @@ testRunner.Then("I should see \"<link rel=\"alternate\" type=\"application/rss\\
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Enabling remote blog publishing inserts the appropriate metaweblogapi markup into" +
" the blog\'s page", ((string[])(null)));
#line 114
#line 128
this.ScenarioSetup(scenarioInfo);
#line 115
testRunner.Given("I have installed Orchard");
#line 116
testRunner.And("I have enabled \"XmlRpc\"");
#line 117
testRunner.And("I have enabled \"Orchard.Blogs.RemotePublishing\"");
#line 118
testRunner.When("I go to \"admin/blogs/create\"");
#line 129
testRunner.Given("I have installed Orchard");
#line 130
testRunner.And("I have enabled \"XmlRpc\"");
#line 131
testRunner.And("I have enabled \"Orchard.Blogs.RemotePublishing\"");
#line 132
testRunner.When("I go to \"admin/blogs/create\"");
#line hidden
TechTalk.SpecFlow.Table table12 = new TechTalk.SpecFlow.Table(new string[] {
"name",
@@ -371,24 +399,165 @@ testRunner.When("I go to \"admin/blogs/create\"");
table12.AddRow(new string[] {
"Routable.Title",
"My Blog"});
#line 119
testRunner.And("I fill in", ((string)(null)), table12);
#line 122
testRunner.And("I hit \"Save\"");
#line 123
testRunner.And("I go to \"my-blog\"");
#line 124
testRunner.Then("I should see \"<link href=\"[^\"]*/XmlRpc/LiveWriter/Manifest\" rel=\"wlwmanifest\" typ" +
#line 133
testRunner.And("I fill in", ((string)(null)), table12);
#line 136
testRunner.And("I hit \"Save\"");
#line 137
testRunner.And("I go to \"my-blog\"");
#line 138
testRunner.Then("I should see \"<link href=\"[^\"]*/XmlRpc/LiveWriter/Manifest\" rel=\"wlwmanifest\" typ" +
"e=\"application/wlwmanifest\\+xml\" />\"");
#line 125
testRunner.When("I go to \"/XmlRpc/LiveWriter/Manifest\"");
#line 126
testRunner.Then("the content type should be \"\\btext/xml\\b\"");
#line 127
testRunner.And("I should see \"<manifest xmlns=\"http\\://schemas\\.microsoft\\.com/wlw/manifest/weblo" +
#line 139
testRunner.When("I go to \"/XmlRpc/LiveWriter/Manifest\"");
#line 140
testRunner.Then("the content type should be \"\\btext/xml\\b\"");
#line 141
testRunner.And("I should see \"<manifest xmlns=\"http\\://schemas\\.microsoft\\.com/wlw/manifest/weblo" +
"g\">\"");
#line 128
testRunner.And("I should see \"<clientType>Metaweblog</clientType>\"");
#line 142
testRunner.And("I should see \"<clientType>Metaweblog</clientType>\"");
#line hidden
testRunner.CollectScenarioErrors();
}
[NUnit.Framework.TestAttribute()]
[NUnit.Framework.DescriptionAttribute("The virtual path of my installation when not at the root is reflected in the URL " +
"example for the slug field when creating a blog or blog post")]
public virtual void TheVirtualPathOfMyInstallationWhenNotAtTheRootIsReflectedInTheURLExampleForTheSlugFieldWhenCreatingABlogOrBlogPost()
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("The virtual path of my installation when not at the root is reflected in the URL " +
"example for the slug field when creating a blog or blog post", ((string[])(null)));
#line 144
this.ScenarioSetup(scenarioInfo);
#line 145
testRunner.Given("I have installed Orchard at \"/OrchardLocal\"");
#line 146
testRunner.When("I go to \"admin/blogs/create\"");
#line 147
testRunner.Then("I should see \"<span>http\\://localhost/OrchardLocal/</span>\"");
#line hidden
TechTalk.SpecFlow.Table table13 = new TechTalk.SpecFlow.Table(new string[] {
"name",
"value"});
table13.AddRow(new string[] {
"Routable.Title",
"My Blog"});
#line 148
testRunner.When("I fill in", ((string)(null)), table13);
#line 151
testRunner.And("I hit \"Save\"");
#line 152
testRunner.And("I go to \"admin/blogs\"");
#line 153
testRunner.And("I follow \"My Blog\"");
#line 154
testRunner.And("I follow \"New Post\"");
#line 155
testRunner.Then("I should see \"<span>http\\://localhost/OrchardLocal/my-blog/</span>\"");
#line hidden
testRunner.CollectScenarioErrors();
}
[NUnit.Framework.TestAttribute()]
[NUnit.Framework.DescriptionAttribute("The virtual path of my installation when at the root is reflected in the URL exam" +
"ple for the slug field when creating a blog or blog post")]
public virtual void TheVirtualPathOfMyInstallationWhenAtTheRootIsReflectedInTheURLExampleForTheSlugFieldWhenCreatingABlogOrBlogPost()
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("The virtual path of my installation when at the root is reflected in the URL exam" +
"ple for the slug field when creating a blog or blog post", ((string[])(null)));
#line 157
this.ScenarioSetup(scenarioInfo);
#line 158
testRunner.Given("I have installed Orchard at \"/\"");
#line 159
testRunner.When("I go to \"admin/blogs/create\"");
#line 160
testRunner.Then("I should see \"<span>http\\://localhost/</span>\"");
#line hidden
TechTalk.SpecFlow.Table table14 = new TechTalk.SpecFlow.Table(new string[] {
"name",
"value"});
table14.AddRow(new string[] {
"Routable.Title",
"My Blog"});
#line 161
testRunner.When("I fill in", ((string)(null)), table14);
#line 164
testRunner.And("I hit \"Save\"");
#line 165
testRunner.And("I go to \"admin/blogs\"");
#line 166
testRunner.And("I follow \"My Blog\"");
#line 167
testRunner.And("I follow \"New Post\"");
#line 168
testRunner.Then("I should see \"<span>http\\://localhost/my-blog/</span>\"");
#line hidden
testRunner.CollectScenarioErrors();
}
[NUnit.Framework.TestAttribute()]
[NUnit.Framework.DescriptionAttribute("I set my blog to be the content for the home page and the posts for the blog be r" +
"ooted to the app")]
public virtual void ISetMyBlogToBeTheContentForTheHomePageAndThePostsForTheBlogBeRootedToTheApp()
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("I set my blog to be the content for the home page and the posts for the blog be r" +
"ooted to the app", ((string[])(null)));
#line 170
this.ScenarioSetup(scenarioInfo);
#line 171
testRunner.Given("I have installed Orchard");
#line 172
testRunner.When("I go to \"admin/blogs/create\"");
#line hidden
TechTalk.SpecFlow.Table table15 = new TechTalk.SpecFlow.Table(new string[] {
"name",
"value"});
table15.AddRow(new string[] {
"Routable.Title",
"My Blog"});
table15.AddRow(new string[] {
"Routable.PromoteToHomePage",
"true"});
#line 173
testRunner.And("I fill in", ((string)(null)), table15);
#line 177
testRunner.And("I hit \"Save\"");
#line 178
testRunner.And("I go to \"admin/blogs\"");
#line 179
testRunner.And("I follow \"My Blog\"");
#line 180
testRunner.And("I follow \"New Post\"");
#line hidden
TechTalk.SpecFlow.Table table16 = new TechTalk.SpecFlow.Table(new string[] {
"name",
"value"});
table16.AddRow(new string[] {
"Routable.Title",
"My Post"});
table16.AddRow(new string[] {
"Body.Text",
"Hi there."});
#line 181
testRunner.And("I fill in", ((string)(null)), table16);
#line 185
testRunner.And("I hit \"Publish Now\"");
#line 186
testRunner.And("I am redirected");
#line 187
testRunner.And("I go to \"/Default.aspx\"");
#line 188
testRunner.Then("I should see \"<h1>My Blog</h1>\"");
#line 189
testRunner.When("I go to \"/my-blog\"");
#line 190
testRunner.Then("the status should be 404 \"Not Found\"");
#line 191
testRunner.When("I go to \"/my-post\"");
#line 192
testRunner.Then("I should see \"<h1>My Post</h1>\"");
#line hidden
testRunner.CollectScenarioErrors();
}

View File

@@ -0,0 +1,44 @@
Feature: Comments
In order to enable simple comment capabilities on my site
As an author
I want to allow comments to be safely posted on specific content item pages
Scenario: HTML markup in any given comment is encoded
Given I have installed Orchard
When I go to "admin/blogs/create"
And I fill in
| name | value |
| Routable.Title | My Blog |
And I hit "Save"
And I go to "admin/blogs"
And I follow "My Blog"
And I follow "New Post"
And I fill in
| name | value |
| Routable.Title | My Post |
| Body.Text | Hi there. |
And I hit "Publish Now"
And I go to "my-blog/my-post"
And I fill in
| name | value |
| CommentText | This is<br id="bad-br" />a <a href="#">link</a>. |
And I hit "Submit Comment"
And I am redirected
# because the ToUrlString extension method breaks in this specific (test) environment, the returnUrl is broken...
And I go to "my-blog/my-post"
Then I should see "This is&lt;br id=&quot;bad-br&quot; /&gt;a &lt;a href"
And I should not see "<br id="bad-br" />"
# another workaround because of ToUrlString in this environment
When I go to "Users/Account/LogOff"
And I am redirected
And I go to "my-blog/my-post"
And I fill in
| name | value |
| Name | Some One |
| CommentText | This is<br id="bad-anon-br" />a <a href="#">link</a>. |
And I hit "Submit Comment"
And I am redirected
# because the ToUrlString extension method breaks in this specific (test) environment, the returnUrl is broken...
And I go to "my-blog/my-post"
Then I should see "This is&lt;br id=&quot;bad-anon-br&quot; /&gt;a &lt;a href"
And I should not see "<br id="bad-anon-br" />"

152
src/Orchard.Specs/Comments.feature.cs generated Normal file
View File

@@ -0,0 +1,152 @@
// ------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by SpecFlow (http://www.specflow.org/).
// SpecFlow Version:1.4.0.0
// Runtime Version:4.0.30319.1
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
// ------------------------------------------------------------------------------
#region Designer generated code
namespace Orchard.Specs
{
using TechTalk.SpecFlow;
[System.CodeDom.Compiler.GeneratedCodeAttribute("TechTalk.SpecFlow", "1.4.0.0")]
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[NUnit.Framework.TestFixtureAttribute()]
[NUnit.Framework.DescriptionAttribute("Comments")]
public partial class CommentsFeature
{
private static TechTalk.SpecFlow.ITestRunner testRunner;
#line 1 "Comments.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"), "Comments", "In order to enable simple comment capabilities on my site\r\nAs an author\r\nI want t" +
"o allow comments to be safely posted on specific content item pages", GenerationTargetLanguage.CSharp, ((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("HTML markup in any given comment is encoded")]
public virtual void HTMLMarkupInAnyGivenCommentIsEncoded()
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("HTML markup in any given comment is encoded", ((string[])(null)));
#line 6
this.ScenarioSetup(scenarioInfo);
#line 7
testRunner.Given("I have installed Orchard");
#line 8
testRunner.When("I go to \"admin/blogs/create\"");
#line hidden
TechTalk.SpecFlow.Table table1 = new TechTalk.SpecFlow.Table(new string[] {
"name",
"value"});
table1.AddRow(new string[] {
"Routable.Title",
"My Blog"});
#line 9
testRunner.And("I fill in", ((string)(null)), table1);
#line 12
testRunner.And("I hit \"Save\"");
#line 13
testRunner.And("I go to \"admin/blogs\"");
#line 14
testRunner.And("I follow \"My Blog\"");
#line 15
testRunner.And("I follow \"New Post\"");
#line hidden
TechTalk.SpecFlow.Table table2 = new TechTalk.SpecFlow.Table(new string[] {
"name",
"value"});
table2.AddRow(new string[] {
"Routable.Title",
"My Post"});
table2.AddRow(new string[] {
"Body.Text",
"Hi there."});
#line 16
testRunner.And("I fill in", ((string)(null)), table2);
#line 20
testRunner.And("I hit \"Publish Now\"");
#line 21
testRunner.And("I go to \"my-blog/my-post\"");
#line hidden
TechTalk.SpecFlow.Table table3 = new TechTalk.SpecFlow.Table(new string[] {
"name",
"value"});
table3.AddRow(new string[] {
"CommentText",
"This is<br id=\"bad-br\" />a <a href=\"#\">link</a>."});
#line 22
testRunner.And("I fill in", ((string)(null)), table3);
#line 25
testRunner.And("I hit \"Submit Comment\"");
#line 26
testRunner.And("I am redirected");
#line 28
testRunner.And("I go to \"my-blog/my-post\"");
#line 29
testRunner.Then("I should see \"This is&lt;br id=&quot;bad-br&quot; /&gt;a &lt;a href\"");
#line 30
testRunner.And("I should not see \"<br id=\"bad-br\" />\"");
#line 32
testRunner.When("I go to \"Users/Account/LogOff\"");
#line 33
testRunner.And("I am redirected");
#line 34
testRunner.And("I go to \"my-blog/my-post\"");
#line hidden
TechTalk.SpecFlow.Table table4 = new TechTalk.SpecFlow.Table(new string[] {
"name",
"value"});
table4.AddRow(new string[] {
"Name",
"Some One"});
table4.AddRow(new string[] {
"CommentText",
"This is<br id=\"bad-anon-br\" />a <a href=\"#\">link</a>."});
#line 35
testRunner.And("I fill in", ((string)(null)), table4);
#line 39
testRunner.And("I hit \"Submit Comment\"");
#line 40
testRunner.And("I am redirected");
#line 42
testRunner.And("I go to \"my-blog/my-post\"");
#line 43
testRunner.Then("I should see \"This is&lt;br id=&quot;bad-anon-br&quot; /&gt;a &lt;a href\"");
#line 44
testRunner.And("I should not see \"<br id=\"bad-anon-br\" />\"");
#line hidden
testRunner.CollectScenarioErrors();
}
}
}
#endregion

View File

@@ -1,6 +1,9 @@
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<compilation targetFramework="4.0">
<assemblies>

View File

@@ -1,5 +1,8 @@
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
</httpHandlers>

View File

@@ -15,7 +15,9 @@
</sectionGroup>
</configSections>
<appSettings/>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.diagnostics configSource="Config\Diagnostics.config"/>
<system.web.webPages.razor>

View File

@@ -4,10 +4,9 @@ using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Hosting;
using HtmlAgilityPack;
using Orchard.Commands;
using Orchard.Specs.Util;
namespace Orchard.Specs.Hosting {
@@ -16,12 +15,13 @@ namespace Orchard.Specs.Hosting {
var physicalPath = Bleroy.FluentPath.Path.Get(webHost.PhysicalDirectory);
urlPath = StripVDir(urlPath, webHost.VirtualDirectory);
var details = new RequestDetails {
HostName = webHost.HostName,
UrlPath = urlPath,
Page = physicalPath
.Combine(urlPath.TrimStart('/', '\\'))
.GetRelativePath(physicalPath),
.GetRelativePath(physicalPath)
};
if (!string.IsNullOrEmpty(webHost.Cookies)) {
@@ -46,12 +46,39 @@ namespace Orchard.Specs.Hosting {
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(';');
var cookieName = setCookie.Split(';')[0].Split('=')[0];
DateTime expires;
if (!string.IsNullOrEmpty(webHost.Cookies)
&& setCookie.Contains("expires=")
&& DateTime.TryParse(setCookie.Split(new[] { "expires=" }, 2, StringSplitOptions.None)[1].Split(';')[0], out expires)
&& expires < DateTime.Now) {
// remove
Trace.WriteLine(string.Format("Removing cookie: {0}", cookieName));
webHost.Cookies = Regex.Replace(webHost.Cookies, string.Format("{0}=[^;]*;?", cookieName), "");
}
else if (!string.IsNullOrEmpty(webHost.Cookies)
&& Regex.IsMatch(webHost.Cookies, string.Format("\b{0}=", cookieName))) {
// replace
Trace.WriteLine(string.Format("Replacing cookie: {0}", cookieName));
webHost.Cookies = Regex.Replace(webHost.Cookies, string.Format("{0}=[^;]*(;?)", cookieName), string.Format("{0}$1", setCookie.Split(';')[0]));
}
else {
// add
Trace.WriteLine(string.Format("Adding cookie: {0}", cookieName));
webHost.Cookies = (webHost.Cookies + ';' + setCookie.Split(';').FirstOrDefault()).Trim(';');
}
Trace.WriteLine(string.Format("Cookie jar: {0}", webHost.Cookies));
}
return details;
}
private static string StripVDir(string urlPath, string virtualDirectory) {
return urlPath.StartsWith(virtualDirectory, StringComparison.OrdinalIgnoreCase)
? urlPath.Substring(virtualDirectory.Length)
: urlPath;
}
public static RequestDetails SendRequest(this WebHost webHost, string urlPath) {
return webHost.SendRequest(urlPath, null);
}

View File

@@ -23,7 +23,9 @@
</sectionGroup>
</configSections>
<appSettings/>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<!--

View File

@@ -137,6 +137,11 @@
<DesignTime>True</DesignTime>
<DependentUpon>Blogs.feature</DependentUpon>
</Compile>
<Compile Include="Comments.feature.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Comments.feature</DependentUpon>
</Compile>
<Compile Include="ContentRights.feature.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
@@ -234,6 +239,10 @@
<Generator>SpecFlowSingleFileGenerator</Generator>
<LastGenOutput>Blogs.feature.cs</LastGenOutput>
</None>
<None Include="Comments.feature">
<Generator>SpecFlowSingleFileGenerator</Generator>
<LastGenOutput>Comments.feature.cs</LastGenOutput>
</None>
<None Include="ContentRights.feature">
<Generator>SpecFlowSingleFileGenerator</Generator>
<LastGenOutput>ContentRights.feature.cs</LastGenOutput>

View File

@@ -39,4 +39,30 @@ Scenario: If I create a page which gets a conflicting path generated its path is
And I hit "Publish Now"
And I go to "super-duper-2"
Then I should see "<h1[^>]*>.*?Super Duper.*?</h1>"
And I should see "This is super number two."
And I should see "This is super number two."
Scenario: A new page marked to be the home page and publish does take over the home page and is not accessible from its own standard path
Given I have installed Orchard
When I go to "admin/contents/create/page"
And I fill in
| name | value |
| Routable.Title | Super Duper |
| Body.Text | This is a draft of the new home page. |
| Routable.PromoteToHomePage | true |
And I hit "Publish Now"
And I go to "/Default.aspx"
Then I should see "<h1>Super Duper</h1>"
When I go to "super-duper"
Then the status should be 404 "Not Found"
Scenario: A new page marked to be the home page but only saved as draft does not take over the home page
Given I have installed Orchard
When I go to "admin/contents/create/page"
And I fill in
| name | value |
| Routable.Title | Drafty |
| Body.Text | This is a draft of the new home page. |
| Routable.PromoteToHomePage | true |
And I hit "Save"
And I go to "/Default.aspx"
Then I should see "<h1>Welcome to Orchard!</h1>"

View File

@@ -1,7 +1,7 @@
// ------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by SpecFlow (http://www.specflow.org/).
// SpecFlow Version:1.3.2.0
// SpecFlow Version:1.4.0.0
// Runtime Version:4.0.30319.1
//
// Changes to this file may cause incorrect behavior and will be lost if
@@ -14,7 +14,7 @@ namespace Orchard.Specs
using TechTalk.SpecFlow;
[System.CodeDom.Compiler.GeneratedCodeAttribute("TechTalk.SpecFlow", "1.3.2.0")]
[System.CodeDom.Compiler.GeneratedCodeAttribute("TechTalk.SpecFlow", "1.4.0.0")]
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[NUnit.Framework.TestFixtureAttribute()]
[NUnit.Framework.DescriptionAttribute("Pages")]
@@ -31,7 +31,7 @@ namespace Orchard.Specs
{
testRunner = TechTalk.SpecFlow.TestRunnerManager.GetTestRunner();
TechTalk.SpecFlow.FeatureInfo featureInfo = new TechTalk.SpecFlow.FeatureInfo(new System.Globalization.CultureInfo("en-US"), "Pages", "In order to add content pages to my site\r\nAs an author\r\nI want to create, publish" +
" and edit pages", ((string[])(null)));
" and edit pages", GenerationTargetLanguage.CSharp, ((string[])(null)));
testRunner.OnFeatureStart(featureInfo);
}
@@ -61,11 +61,11 @@ namespace Orchard.Specs
#line 6
this.ScenarioSetup(scenarioInfo);
#line 7
testRunner.Given("I have installed Orchard");
testRunner.Given("I have installed Orchard");
#line 8
testRunner.When("I go to \"admin\"");
testRunner.When("I go to \"admin\"");
#line 9
testRunner.Then("I should see \"<a href=\"/Admin/Contents/Create/Page\">Page</a>\"");
testRunner.Then("I should see \"<a href=\"/Admin/Contents/Create/Page\">Page</a>\"");
#line hidden
testRunner.CollectScenarioErrors();
}
@@ -78,9 +78,9 @@ testRunner.Then("I should see \"<a href=\"/Admin/Contents/Create/Page\">Page</a>
#line 11
this.ScenarioSetup(scenarioInfo);
#line 12
testRunner.Given("I have installed Orchard");
testRunner.Given("I have installed Orchard");
#line 13
testRunner.When("I go to \"admin/contents/create/page\"");
testRunner.When("I go to \"admin/contents/create/page\"");
#line hidden
TechTalk.SpecFlow.Table table1 = new TechTalk.SpecFlow.Table(new string[] {
"name",
@@ -92,15 +92,15 @@ testRunner.When("I go to \"admin/contents/create/page\"");
"Body.Text",
"This is super."});
#line 14
testRunner.And("I fill in", ((string)(null)), table1);
testRunner.And("I fill in", ((string)(null)), table1);
#line 18
testRunner.And("I hit \"Publish Now\"");
testRunner.And("I hit \"Publish Now\"");
#line 19
testRunner.And("I go to \"super-duper\"");
testRunner.And("I go to \"super-duper\"");
#line 20
testRunner.Then("I should see \"<h1[^>]*>.*?Super Duper.*?</h1>\"");
testRunner.Then("I should see \"<h1[^>]*>.*?Super Duper.*?</h1>\"");
#line 21
testRunner.And("I should see \"This is super.\"");
testRunner.And("I should see \"This is super.\"");
#line hidden
testRunner.CollectScenarioErrors();
}
@@ -115,9 +115,9 @@ testRunner.And("I should see \"This is super.\"");
#line 23
this.ScenarioSetup(scenarioInfo);
#line 24
testRunner.Given("I have installed Orchard");
testRunner.Given("I have installed Orchard");
#line 25
testRunner.When("I go to \"admin/contents/create/page\"");
testRunner.When("I go to \"admin/contents/create/page\"");
#line hidden
TechTalk.SpecFlow.Table table2 = new TechTalk.SpecFlow.Table(new string[] {
"name",
@@ -129,17 +129,17 @@ testRunner.When("I go to \"admin/contents/create/page\"");
"Body.Text",
"This is super."});
#line 26
testRunner.And("I fill in", ((string)(null)), table2);
testRunner.And("I fill in", ((string)(null)), table2);
#line 30
testRunner.And("I hit \"Publish Now\"");
testRunner.And("I hit \"Publish Now\"");
#line 31
testRunner.And("I go to \"super-duper\"");
testRunner.And("I go to \"super-duper\"");
#line 32
testRunner.Then("I should see \"<h1[^>]*>.*?Super Duper.*?</h1>\"");
testRunner.Then("I should see \"<h1[^>]*>.*?Super Duper.*?</h1>\"");
#line 33
testRunner.And("I should see \"This is super.\"");
testRunner.And("I should see \"This is super.\"");
#line 34
testRunner.When("I go to \"admin/contents/create/page\"");
testRunner.When("I go to \"admin/contents/create/page\"");
#line hidden
TechTalk.SpecFlow.Table table3 = new TechTalk.SpecFlow.Table(new string[] {
"name",
@@ -151,15 +151,95 @@ testRunner.When("I go to \"admin/contents/create/page\"");
"Body.Text",
"This is super number two."});
#line 35
testRunner.And("I fill in", ((string)(null)), table3);
testRunner.And("I fill in", ((string)(null)), table3);
#line 39
testRunner.And("I hit \"Publish Now\"");
testRunner.And("I hit \"Publish Now\"");
#line 40
testRunner.And("I go to \"super-duper-2\"");
testRunner.And("I go to \"super-duper-2\"");
#line 41
testRunner.Then("I should see \"<h1[^>]*>.*?Super Duper.*?</h1>\"");
testRunner.Then("I should see \"<h1[^>]*>.*?Super Duper.*?</h1>\"");
#line 42
testRunner.And("I should see \"This is super number two.\"");
testRunner.And("I should see \"This is super number two.\"");
#line hidden
testRunner.CollectScenarioErrors();
}
[NUnit.Framework.TestAttribute()]
[NUnit.Framework.DescriptionAttribute("A new page marked to be the home page and publish does take over the home page an" +
"d is not accessible from its own standard path")]
public virtual void ANewPageMarkedToBeTheHomePageAndPublishDoesTakeOverTheHomePageAndIsNotAccessibleFromItsOwnStandardPath()
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("A new page marked to be the home page and publish does take over the home page an" +
"d is not accessible from its own standard path", ((string[])(null)));
#line 44
this.ScenarioSetup(scenarioInfo);
#line 45
testRunner.Given("I have installed Orchard");
#line 46
testRunner.When("I go to \"admin/contents/create/page\"");
#line hidden
TechTalk.SpecFlow.Table table4 = new TechTalk.SpecFlow.Table(new string[] {
"name",
"value"});
table4.AddRow(new string[] {
"Routable.Title",
"Super Duper"});
table4.AddRow(new string[] {
"Body.Text",
"This is a draft of the new home page."});
table4.AddRow(new string[] {
"Routable.PromoteToHomePage",
"true"});
#line 47
testRunner.And("I fill in", ((string)(null)), table4);
#line 52
testRunner.And("I hit \"Publish Now\"");
#line 53
testRunner.And("I go to \"/Default.aspx\"");
#line 54
testRunner.Then("I should see \"<h1>Super Duper</h1>\"");
#line 55
testRunner.When("I go to \"super-duper\"");
#line 56
testRunner.Then("the status should be 404 \"Not Found\"");
#line hidden
testRunner.CollectScenarioErrors();
}
[NUnit.Framework.TestAttribute()]
[NUnit.Framework.DescriptionAttribute("A new page marked to be the home page but only saved as draft does not take over " +
"the home page")]
public virtual void ANewPageMarkedToBeTheHomePageButOnlySavedAsDraftDoesNotTakeOverTheHomePage()
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("A new page marked to be the home page but only saved as draft does not take over " +
"the home page", ((string[])(null)));
#line 58
this.ScenarioSetup(scenarioInfo);
#line 59
testRunner.Given("I have installed Orchard");
#line 60
testRunner.When("I go to \"admin/contents/create/page\"");
#line hidden
TechTalk.SpecFlow.Table table5 = new TechTalk.SpecFlow.Table(new string[] {
"name",
"value"});
table5.AddRow(new string[] {
"Routable.Title",
"Drafty"});
table5.AddRow(new string[] {
"Body.Text",
"This is a draft of the new home page."});
table5.AddRow(new string[] {
"Routable.PromoteToHomePage",
"true"});
#line 61
testRunner.And("I fill in", ((string)(null)), table5);
#line 66
testRunner.And("I hit \"Save\"");
#line 67
testRunner.And("I go to \"/Default.aspx\"");
#line 68
testRunner.Then("I should see \"<h1>Welcome to Orchard!</h1>\"");
#line hidden
testRunner.CollectScenarioErrors();
}

View File

@@ -6,9 +6,9 @@ Feature: Setup
Scenario: Root request shows setup form
Given I have a clean site with
| extension | names |
| module | Orchard.Setup, Orchard.Pages, Orchard.Users, Orchard.Roles, Orchard.Messaging, Orchard.Comments, Orchard.PublishLater, Orchard.Themes, Orchard.jQuery, TinyMce |
| core | Common, Contents, Dashboard, Feeds, HomePage, Navigation, Routable, Scheduling, Settings, Shapes, XmlRpc |
| theme | SafeMode |
| Module | Orchard.Setup, Orchard.Pages, Orchard.Users, Orchard.Roles, Orchard.Messaging, Orchard.Comments, Orchard.PublishLater, Orchard.Themes, Orchard.jQuery, TinyMce |
| Core | Common, Contents, Dashboard, Feeds, HomePage, Navigation, Routable, Scheduling, Settings, Shapes, XmlRpc |
| Theme | SafeMode |
When I go to "/Default.aspx"
Then I should see "Welcome to Orchard"
And I should see "Finish Setup"
@@ -17,9 +17,9 @@ Scenario: Root request shows setup form
Scenario: Setup folder also shows setup form
Given I have a clean site with
| extension | names |
| module | Orchard.Setup, Orchard.Pages, Orchard.Users, Orchard.Roles, Orchard.Messaging, Orchard.Comments, Orchard.PublishLater, Orchard.Themes, Orchard.jQuery, TinyMce |
| core | Common, Contents, Dashboard, Feeds, HomePage, Navigation, Routable, Scheduling, Settings, Shapes, XmlRpc |
| theme | SafeMode |
| Module | Orchard.Setup, Orchard.Pages, Orchard.Users, Orchard.Roles, Orchard.Messaging, Orchard.Comments, Orchard.PublishLater, Orchard.Themes, Orchard.jQuery, TinyMce |
| Core | Common, Contents, Dashboard, Feeds, HomePage, Navigation, Routable, Scheduling, Settings, Shapes, XmlRpc |
| Theme | SafeMode |
When I go to "/Setup"
Then I should see "Welcome to Orchard"
And I should see "Finish Setup"
@@ -28,9 +28,9 @@ Scenario: Setup folder also shows setup form
Scenario: Some of the initial form values are required
Given I have a clean site with
| extension | names |
| module | Orchard.Setup, Orchard.Pages, Orchard.Users, Orchard.Roles, Orchard.Messaging, Orchard.Comments, Orchard.PublishLater, Orchard.Themes, Orchard.jQuery, TinyMce |
| core | Common, Contents, Dashboard, Feeds, HomePage, Navigation, Routable, Scheduling, Settings, Shapes, XmlRpc |
| theme | SafeMode |
| Module | Orchard.Setup, Orchard.Pages, Orchard.Users, Orchard.Roles, Orchard.Messaging, Orchard.Comments, Orchard.PublishLater, Orchard.Themes, Orchard.jQuery, TinyMce |
| Core | Common, Contents, Dashboard, Feeds, HomePage, Navigation, Routable, Scheduling, Settings, Shapes, XmlRpc |
| Theme | SafeMode |
When I go to "/Setup"
And I hit "Finish Setup"
Then I should see "<input autofocus="autofocus" class="input-validation-error" id="SiteName" name="SiteName" type="text" value="" />"
@@ -39,9 +39,9 @@ Scenario: Some of the initial form values are required
Scenario: Calling setup on a brand new install
Given I have a clean site with
| extension | names |
| module | Orchard.Setup, Orchard.Pages, Orchard.Users, Orchard.Roles, Orchard.Messaging, Orchard.Scripting, Orchard.Comments, Orchard.PublishLater, Orchard.Themes, Orchard.Modules, Orchard.Widgets, Orchard.jQuery, TinyMce |
| core | Common, Contents, Dashboard, Feeds, HomePage, Navigation, Routable, Scheduling, Settings, Shapes, XmlRpc |
| theme | SafeMode, TheThemeMachine |
| Module | Orchard.Setup, Orchard.Pages, Orchard.Users, Orchard.Roles, Orchard.Messaging, Orchard.Scripting, Orchard.Comments, Orchard.PublishLater, Orchard.Themes, Orchard.Modules, Orchard.Widgets, Orchard.jQuery, TinyMce |
| Core | Common, Contents, Dashboard, Feeds, HomePage, Navigation, Routable, Scheduling, Settings, Shapes, XmlRpc |
| Theme | SafeMode, TheThemeMachine |
And I am on "/Setup"
When I fill in
| name | value |

View File

@@ -65,15 +65,15 @@ this.ScenarioSetup(scenarioInfo);
"extension",
"names"});
table1.AddRow(new string[] {
"module",
"Module",
"Orchard.Setup, Orchard.Pages, Orchard.Users, Orchard.Roles, Orchard.Messaging, Or" +
"chard.Comments, Orchard.PublishLater, Orchard.Themes, Orchard.jQuery, TinyMce"});
table1.AddRow(new string[] {
"core",
"Core",
"Common, Contents, Dashboard, Feeds, HomePage, Navigation, Routable, Scheduling, S" +
"ettings, Shapes, XmlRpc"});
table1.AddRow(new string[] {
"theme",
"Theme",
"SafeMode"});
#line 7
testRunner.Given("I have a clean site with", ((string)(null)), table1);
@@ -101,15 +101,15 @@ this.ScenarioSetup(scenarioInfo);
"extension",
"names"});
table2.AddRow(new string[] {
"module",
"Module",
"Orchard.Setup, Orchard.Pages, Orchard.Users, Orchard.Roles, Orchard.Messaging, Or" +
"chard.Comments, Orchard.PublishLater, Orchard.Themes, Orchard.jQuery, TinyMce"});
table2.AddRow(new string[] {
"core",
"Core",
"Common, Contents, Dashboard, Feeds, HomePage, Navigation, Routable, Scheduling, S" +
"ettings, Shapes, XmlRpc"});
table2.AddRow(new string[] {
"theme",
"Theme",
"SafeMode"});
#line 18
testRunner.Given("I have a clean site with", ((string)(null)), table2);
@@ -137,15 +137,15 @@ this.ScenarioSetup(scenarioInfo);
"extension",
"names"});
table3.AddRow(new string[] {
"module",
"Module",
"Orchard.Setup, Orchard.Pages, Orchard.Users, Orchard.Roles, Orchard.Messaging, Or" +
"chard.Comments, Orchard.PublishLater, Orchard.Themes, Orchard.jQuery, TinyMce"});
table3.AddRow(new string[] {
"core",
"Core",
"Common, Contents, Dashboard, Feeds, HomePage, Navigation, Routable, Scheduling, S" +
"ettings, Shapes, XmlRpc"});
table3.AddRow(new string[] {
"theme",
"Theme",
"SafeMode"});
#line 29
testRunner.Given("I have a clean site with", ((string)(null)), table3);
@@ -175,16 +175,16 @@ this.ScenarioSetup(scenarioInfo);
"extension",
"names"});
table4.AddRow(new string[] {
"module",
"Module",
"Orchard.Setup, Orchard.Pages, Orchard.Users, Orchard.Roles, Orchard.Messaging, Or" +
"chard.Scripting, Orchard.Comments, Orchard.PublishLater, Orchard.Themes, Orchard" +
".Modules, Orchard.Widgets, Orchard.jQuery, TinyMce"});
table4.AddRow(new string[] {
"core",
"Core",
"Common, Contents, Dashboard, Feeds, HomePage, Navigation, Routable, Scheduling, S" +
"ettings, Shapes, XmlRpc"});
table4.AddRow(new string[] {
"theme",
"Theme",
"SafeMode, TheThemeMachine"});
#line 40
testRunner.Given("I have a clean site with", ((string)(null)), table4);

View File

@@ -1,7 +1,7 @@
// ------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by SpecFlow (http://www.specflow.org/).
// SpecFlow Version:1.3.2.0
// SpecFlow Version:1.4.0.0
// Runtime Version:4.0.30319.1
//
// Changes to this file may cause incorrect behavior and will be lost if
@@ -14,7 +14,7 @@ namespace Orchard.Specs
using TechTalk.SpecFlow;
[System.CodeDom.Compiler.GeneratedCodeAttribute("TechTalk.SpecFlow", "1.3.2.0")]
[System.CodeDom.Compiler.GeneratedCodeAttribute("TechTalk.SpecFlow", "1.4.0.0")]
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[NUnit.Framework.TestFixtureAttribute()]
[NUnit.Framework.DescriptionAttribute("Web Hosting")]
@@ -31,7 +31,7 @@ namespace Orchard.Specs
{
testRunner = TechTalk.SpecFlow.TestRunnerManager.GetTestRunner();
TechTalk.SpecFlow.FeatureInfo featureInfo = new TechTalk.SpecFlow.FeatureInfo(new System.Globalization.CultureInfo("en-US"), "Web Hosting", "In order to test orchard\r\nAs an integration runner\r\nI want to verify basic hostin" +
"g is working", ((string[])(null)));
"g is working", GenerationTargetLanguage.CSharp, ((string[])(null)));
testRunner.OnFeatureStart(featureInfo);
}
@@ -61,13 +61,13 @@ namespace Orchard.Specs
#line 6
this.ScenarioSetup(scenarioInfo);
#line 7
testRunner.Given("I have a clean site based on Simple.Web");
testRunner.Given("I have a clean site based on Simple.Web");
#line 8
testRunner.When("I go to \"Content/Static.txt\"");
testRunner.When("I go to \"Content/Static.txt\"");
#line 9
testRunner.Then("I should see \"Hello world!\"");
testRunner.Then("I should see \"Hello world!\"");
#line 10
testRunner.And("the status should be 200 \"OK\"");
testRunner.And("the status should be 200 \"OK\"");
#line hidden
testRunner.CollectScenarioErrors();
}
@@ -80,13 +80,13 @@ testRunner.And("the status should be 200 \"OK\"");
#line 12
this.ScenarioSetup(scenarioInfo);
#line 13
testRunner.Given("I have a clean site based on Simple.Web");
testRunner.Given("I have a clean site based on Simple.Web");
#line 14
testRunner.When("I go to \"Simple/Page.aspx\"");
testRunner.When("I go to \"Simple/Page.aspx\"");
#line 15
testRunner.Then("I should see \"Hello again\"");
testRunner.Then("I should see \"Hello again\"");
#line 16
testRunner.And("the status should be 200 \"OK\"");
testRunner.And("the status should be 200 \"OK\"");
#line hidden
testRunner.CollectScenarioErrors();
}
@@ -99,13 +99,13 @@ testRunner.And("the status should be 200 \"OK\"");
#line 18
this.ScenarioSetup(scenarioInfo);
#line 19
testRunner.Given("I have a clean site based on Simple.Web");
testRunner.Given("I have a clean site based on Simple.Web");
#line 20
testRunner.When("I go to \"hello-world\"");
testRunner.When("I go to \"hello-world\"");
#line 21
testRunner.Then("the status should be 200 \"OK\"");
testRunner.Then("the status should be 200 \"OK\"");
#line 22
testRunner.And("I should see \"Hello yet again\"");
testRunner.And("I should see \"Hello yet again\"");
#line hidden
testRunner.CollectScenarioErrors();
}
@@ -118,15 +118,15 @@ testRunner.And("I should see \"Hello yet again\"");
#line 24
this.ScenarioSetup(scenarioInfo);
#line 25
testRunner.Given("I have a clean site based on Simple.Web");
testRunner.Given("I have a clean site based on Simple.Web");
#line 26
testRunner.When("I go to \"/simple/page.aspx\"");
testRunner.When("I go to \"/simple/page.aspx\"");
#line 27
testRunner.And("I follow \"next page\"");
testRunner.And("I follow \"next page\"");
#line 28
testRunner.Then("the status should be 200 \"OK\"");
testRunner.Then("the status should be 200 \"OK\"");
#line 29
testRunner.And("I should see \"Hello yet again\"");
testRunner.And("I should see \"Hello yet again\"");
#line hidden
testRunner.CollectScenarioErrors();
}
@@ -139,9 +139,9 @@ testRunner.And("I should see \"Hello yet again\"");
#line 31
this.ScenarioSetup(scenarioInfo);
#line 32
testRunner.Given("I have a clean site based on Simple.Web");
testRunner.Given("I have a clean site based on Simple.Web");
#line 33
testRunner.And("I am on \"/simple/page.aspx\"");
testRunner.And("I am on \"/simple/page.aspx\"");
#line hidden
TechTalk.SpecFlow.Table table1 = new TechTalk.SpecFlow.Table(new string[] {
"name",
@@ -150,15 +150,15 @@ testRunner.And("I am on \"/simple/page.aspx\"");
"input1",
"gamma"});
#line 34
testRunner.When("I fill in", ((string)(null)), table1);
testRunner.When("I fill in", ((string)(null)), table1);
#line 37
testRunner.And("I hit \"Go!\"");
testRunner.And("I hit \"Go!\"");
#line 38
testRunner.Then("I should see \"passthrough1:alpha\"");
testRunner.Then("I should see \"passthrough1:alpha\"");
#line 39
testRunner.And("I should see \"passthrough2:beta\"");
testRunner.And("I should see \"passthrough2:beta\"");
#line 40
testRunner.And("I should see \"input1:gamma\"");
testRunner.And("I should see \"input1:gamma\"");
#line hidden
testRunner.CollectScenarioErrors();
}
@@ -171,13 +171,13 @@ testRunner.And("I should see \"input1:gamma\"");
#line 42
this.ScenarioSetup(scenarioInfo);
#line 43
testRunner.Given("I have a clean site based on Simple.Web");
testRunner.Given("I have a clean site based on Simple.Web");
#line 44
testRunner.When("I go to \"/simple/cookie-set.aspx\"");
testRunner.When("I go to \"/simple/cookie-set.aspx\"");
#line 45
testRunner.And("I go to \"/simple/cookie-show.aspx\"");
testRunner.And("I go to \"/simple/cookie-show.aspx\"");
#line 46
testRunner.Then("I should see \"foo:bar\"");
testRunner.Then("I should see \"foo:bar\"");
#line hidden
testRunner.CollectScenarioErrors();
}
@@ -190,13 +190,13 @@ testRunner.Then("I should see \"foo:bar\"");
#line 48
this.ScenarioSetup(scenarioInfo);
#line 49
testRunner.Given("I have a clean site based on Simple.Web");
testRunner.Given("I have a clean site based on Simple.Web");
#line 50
testRunner.When("I go to \"/simple/redir.aspx\"");
testRunner.When("I go to \"/simple/redir.aspx\"");
#line 51
testRunner.And("I am redirected");
testRunner.And("I am redirected");
#line 52
testRunner.Then("I should see \"Hello again\"");
testRunner.Then("I should see \"Hello again\"");
#line hidden
testRunner.CollectScenarioErrors();
}
@@ -209,11 +209,11 @@ testRunner.Then("I should see \"Hello again\"");
#line 54
this.ScenarioSetup(scenarioInfo);
#line 55
testRunner.Given("I have a clean site based on Simple.Web");
testRunner.Given("I have a clean site based on Simple.Web");
#line 56
testRunner.When("I go to \"/Modules/Orchard.Blogs/module.txt\"");
testRunner.When("I go to \"/Modules/Orchard.Blogs/module.txt\"");
#line 57
testRunner.Then("the status should be 404 \"Not Found\"");
testRunner.Then("the status should be 404 \"Not Found\"");
#line hidden
testRunner.CollectScenarioErrors();
}
@@ -226,11 +226,11 @@ testRunner.Then("the status should be 404 \"Not Found\"");
#line 59
this.ScenarioSetup(scenarioInfo);
#line 60
testRunner.Given("I have a clean site based on Simple.Web");
testRunner.Given("I have a clean site based on Simple.Web");
#line 61
testRunner.When("I go to \"/Themes/Classic/theme.txt\"");
testRunner.When("I go to \"/Themes/Classic/theme.txt\"");
#line 62
testRunner.Then("the status should be 404 \"Not Found\"");
testRunner.Then("the status should be 404 \"Not Found\"");
#line hidden
testRunner.CollectScenarioErrors();
}

View File

@@ -123,7 +123,7 @@ Features:
public IEnumerable<ExtensionDescriptor> AvailableExtensions() {
foreach (var e in Manifests) {
string name = e.Key;
yield return ExtensionFolders.GetDescriptorForExtension("~/", name, "Module", Manifests[name]);
yield return ExtensionFolders.GetDescriptorForExtension("~/", name, DefaultExtensionTypes.Module, Manifests[name]);
}
}
}

View File

@@ -1,12 +1,8 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Packaging;
using System.Linq;
using System.Text;
using Autofac;
using NUnit.Framework;
using Orchard.Environment.Extensions;
using Orchard.Environment.Extensions.Models;
using Orchard.FileSystems.WebSite;
using Orchard.Packaging.Services;
@@ -30,7 +26,7 @@ namespace Orchard.Tests.Modules.Packaging {
}
return packageBuilder.BuildPackage(new ExtensionDescriptor {
ExtensionType = "Module",
ExtensionType = DefaultExtensionTypes.Module,
Id = "Hello.World",
Version = "1.0",
Description = "a",

View File

@@ -1,12 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Packaging;
using System.Linq;
using System.Text;
using System.IO;
using Autofac;
using NUnit.Framework;
using Orchard.Environment.Extensions;
using Orchard.Environment.Extensions.Models;
using Orchard.FileSystems.VirtualPath;
using Orchard.FileSystems.WebSite;
@@ -27,7 +21,7 @@ namespace Orchard.Tests.Modules.Packaging {
private Stream BuildHelloWorld(IPackageBuilder packageBuilder) {
return packageBuilder.BuildPackage(new ExtensionDescriptor {
ExtensionType = "Module",
ExtensionType = DefaultExtensionTypes.Module,
Id = "Hello.World",
Version = "1.0",
Description = "a",

View File

@@ -191,6 +191,7 @@ namespace Orchard.Tests.Modules.Users.Controllers {
registrationSettings.UsersCanRegister = true;
registrationSettings.UsersAreModerated = true;
registrationSettings.NotifyModeration = true;
registrationSettings.NotificationsRecipients = "admin";
_container.Resolve<IWorkContextAccessor>().GetContext().CurrentSite.As<SiteSettingsPart>().SuperUser = "admin";
_session.Flush();
@@ -231,13 +232,14 @@ namespace Orchard.Tests.Modules.Users.Controllers {
public void ResetPasswordLinkShouldBeSent() {
var registrationSettings = _container.Resolve<IWorkContextAccessor>().GetContext().CurrentSite.As<RegistrationSettingsPart>();
registrationSettings.UsersCanRegister = true;
registrationSettings.EnableLostPassword = true;
_session.Flush();
_controller.Register("bar", "bar@baz.com", "66554321", "66554321");
_session.Flush();
_controller.Url = new UrlHelper(new RequestContext(new HttpContextStub(), new RouteData()));
var result = _controller.LostPassword("bar");
var result = _controller.RequestLostPassword("bar");
Assert.That(result, Is.TypeOf<RedirectToRouteResult>());
Assert.That(((RedirectToRouteResult)result).RouteValues["action"], Is.EqualTo("LogOn"));

View File

@@ -14,7 +14,21 @@ namespace Orchard.Tests {
Resolve(_container);
}
#if false
// technically more accurate, and doesn't work
[SetUp]
public virtual void Init() {
var hostBuilder = new ContainerBuilder();
var hostContainer = hostBuilder.Build();
var shellContainer = hostContainer.BeginLifetimeScope("shell", shellBuilder => Register(shellBuilder));
var workContainer = shellContainer.BeginLifetimeScope("work");
_container = workContainer;
Resolve(_container);
}
#endif
protected virtual void Register(ContainerBuilder builder) { }
protected virtual void Resolve(IContainer container) { }
protected virtual void Resolve(ILifetimeScope container) { }
}
}

View File

@@ -90,7 +90,7 @@ namespace Orchard.Tests.DataMigration {
public IEnumerable<ExtensionDescriptor> AvailableExtensions() {
foreach (var e in Manifests) {
string name = e.Key;
yield return ExtensionFolders.GetDescriptorForExtension("~/", name, "Module", Manifests[name]);
yield return ExtensionFolders.GetDescriptorForExtension("~/", name, DefaultExtensionTypes.Module, Manifests[name]);
}
}
}

View File

@@ -21,14 +21,14 @@ namespace Orchard.Tests.DisplayManagement.Descriptors {
Id = "Theme1",
Extension = new ExtensionDescriptor {
Id = "Theme1",
ExtensionType = "Theme"
ExtensionType = DefaultExtensionTypes.Theme
}
},
new FeatureDescriptor {
Id = "DerivedTheme",
Extension = new ExtensionDescriptor {
Id = "DerivedTheme",
ExtensionType = "Theme",
ExtensionType = DefaultExtensionTypes.Theme,
BaseTheme = "BaseTheme"
}
},
@@ -36,7 +36,7 @@ namespace Orchard.Tests.DisplayManagement.Descriptors {
Id = "BaseTheme",
Extension = new ExtensionDescriptor {
Id = "BaseTheme",
ExtensionType = "Theme"
ExtensionType = DefaultExtensionTypes.Theme
}
}
};
@@ -69,7 +69,7 @@ namespace Orchard.Tests.DisplayManagement.Descriptors {
Dependencies = Enumerable.Empty<string>(),
Extension = new ExtensionDescriptor {
Id = "Testing",
ExtensionType = "Module",
ExtensionType = DefaultExtensionTypes.Module,
}
}
};

View File

@@ -21,7 +21,7 @@ namespace Orchard.Tests.DisplayManagement.Descriptors {
}
protected override void Resolve(IContainer container) {
protected override void Resolve(ILifetimeScope container) {
_parser = container.Resolve<IPlacementFileParser>();
_folder = container.Resolve<InMemoryWebSiteFolder>();
}

View File

@@ -19,7 +19,7 @@ namespace Orchard.Tests.DisplayManagement.Descriptors {
public class ShapeAttributeBindingStrategyTests : ContainerTestBase {
private Feature _testFeature;
protected override void Register([NotNull] Autofac.ContainerBuilder builder) {
protected override void Register([NotNull] ContainerBuilder builder) {
if (builder == null) {
throw new ArgumentNullException("builder");
}
@@ -29,7 +29,7 @@ namespace Orchard.Tests.DisplayManagement.Descriptors {
Id = "Testing",
Extension = new ExtensionDescriptor {
Id = "Testing",
ExtensionType = "Module",
ExtensionType = DefaultExtensionTypes.Module,
}
}
};
@@ -39,7 +39,7 @@ namespace Orchard.Tests.DisplayManagement.Descriptors {
builder.RegisterModule(new ShapeAttributeBindingModule());
}
protected override void Resolve(IContainer container) {
protected override void Resolve(ILifetimeScope container) {
// implementation resorts to orchard host to resolve "current scope" services
container.Resolve<Mock<IOrchardHostContainer>>()
.Setup(x => x.Resolve<IComponentContext>())

View File

@@ -97,7 +97,7 @@ namespace Orchard.Tests.DisplayManagement.Descriptors {
}
}
protected override void Resolve(IContainer container) {
protected override void Resolve(ILifetimeScope container) {
_features = new List<FeatureDescriptor>();
container.Resolve<Mock<IExtensionManager>>()

View File

@@ -28,7 +28,7 @@ namespace Orchard.Tests.DisplayManagement {
Extension = new ExtensionDescriptor
{
Id = "Testing",
ExtensionType = "Module",
ExtensionType = DefaultExtensionTypes.Module,
}
}
};

View File

@@ -22,11 +22,12 @@ namespace Orchard.Tests.Environment {
}
protected override void Register(ContainerBuilder builder) {
builder.RegisterModule(new WorkContextModule());
builder.RegisterType<WorkContextAccessor>().As<IWorkContextAccessor>();
builder.RegisterAutoMocking();
}
protected override void Resolve(IContainer container) {
protected override void Resolve(ILifetimeScope container) {
container.Mock<IHttpContextAccessor>()
.Setup(x => x.Current())
.Returns(() => _httpContextCurrent);

View File

@@ -23,7 +23,7 @@ namespace Orchard.Tests.Environment.Extensions {
[SetUp]
public void Init() {
var builder = new ContainerBuilder();
_folders = new StubFolders("Module");
_folders = new StubFolders(DefaultExtensionTypes.Module);
builder.RegisterInstance(_folders).As<IExtensionFolders>();
builder.RegisterType<ExtensionManager>().As<IExtensionManager>();
builder.RegisterType<StubCacheManager>().As<ICacheManager>();
@@ -254,7 +254,7 @@ Features:
[Test]
public void ExtensionManagerShouldLoadFeatures() {
var extensionLoader = new StubLoaders();
var extensionFolder = new StubFolders("Module");
var extensionFolder = new StubFolders(DefaultExtensionTypes.Module);
extensionFolder.Manifests.Add("TestModule", @"
Name: TestModule
@@ -280,7 +280,7 @@ Features:
[Test]
public void ExtensionManagerFeaturesContainNonAbstractClasses() {
var extensionLoader = new StubLoaders();
var extensionFolder = new StubFolders("Module");
var extensionFolder = new StubFolders(DefaultExtensionTypes.Module);
extensionFolder.Manifests.Add("TestModule", @"
Name: TestModule
@@ -315,7 +315,7 @@ Features:
[Test]
public void ExtensionManagerTestFeatureAttribute() {
var extensionLoader = new StubLoaders();
var extensionFolder = new StubFolders("Module");
var extensionFolder = new StubFolders(DefaultExtensionTypes.Module);
extensionFolder.Manifests.Add("TestModule", @"
Name: TestModule
@@ -345,7 +345,7 @@ Features:
[Test]
public void ExtensionManagerLoadFeatureReturnsTypesFromSpecificFeaturesWithFeatureAttribute() {
var extensionLoader = new StubLoaders();
var extensionFolder = new StubFolders("Module");
var extensionFolder = new StubFolders(DefaultExtensionTypes.Module);
extensionFolder.Manifests.Add("TestModule", @"
Name: TestModule
@@ -373,7 +373,7 @@ Features:
[Test]
public void ExtensionManagerLoadFeatureDoesNotReturnTypesFromNonMatchingFeatures() {
var extensionLoader = new StubLoaders();
var extensionFolder = new StubFolders("Module");
var extensionFolder = new StubFolders(DefaultExtensionTypes.Module);
extensionFolder.Manifests.Add("TestModule", @"
Name: TestModule
@@ -402,7 +402,7 @@ Features:
[Test]
public void ModuleNameIsIntroducedAsFeatureImplicitly() {
var extensionLoader = new StubLoaders();
var extensionFolder = new StubFolders("Module");
var extensionFolder = new StubFolders(DefaultExtensionTypes.Module);
extensionFolder.Manifests.Add("Minimalistic", @"
Name: Minimalistic
@@ -421,7 +421,7 @@ OrchardVersion: 1
[Test]
public void ThemeNameIsIntroducedAsFeatureImplicitly() {
var extensionLoader = new StubLoaders();
var extensionFolder = new StubFolders("Theme");
var extensionFolder = new StubFolders(DefaultExtensionTypes.Theme);
extensionFolder.Manifests.Add("Minimalistic", @"
Name: Minimalistic

View File

@@ -41,7 +41,7 @@ namespace Orchard.Tests.Environment.Extensions {
}
public StubFolders()
: this("Module") {
: this(DefaultExtensionTypes.Module) {
}
public IDictionary<string, string> Manifests { get; set; }
@@ -459,7 +459,7 @@ Features:
public void FeatureDescriptorsShouldBeLoadedInThemes() {
var extensionLoader = new StubLoaders();
var moduleExtensionFolder = new StubFolders();
var themeExtensionFolder = new StubFolders("Theme");
var themeExtensionFolder = new StubFolders(DefaultExtensionTypes.Theme);
moduleExtensionFolder.Manifests.Add("Alpha", @"
Name: Alpha
@@ -499,7 +499,7 @@ OrchardVersion: 1
public void ThemeFeatureDescriptorsShouldBeAbleToDependOnModules() {
var extensionLoader = new StubLoaders();
var moduleExtensionFolder = new StubFolders();
var themeExtensionFolder = new StubFolders("Theme");
var themeExtensionFolder = new StubFolders(DefaultExtensionTypes.Theme);
moduleExtensionFolder.Manifests.Add("Alpha", @"
Name: Alpha

View File

@@ -21,6 +21,7 @@ namespace Orchard.Tests.Environment.ShellBuilders {
public void Init() {
var builder = new ContainerBuilder();
builder.RegisterType<ShellContextFactory>().As<IShellContextFactory>();
builder.RegisterModule(new WorkContextModule());
builder.RegisterType<WorkContextAccessor>().As<IWorkContextAccessor>();
builder.RegisterAutoMocking(Moq.MockBehavior.Strict);
_container = builder.Build();

View File

@@ -23,6 +23,7 @@ namespace Orchard.Tests.Environment.State {
public void Init() {
var builder = new ContainerBuilder();
builder.RegisterType<DefaultProcessingEngine>().As<IProcessingEngine>();
builder.RegisterModule(new WorkContextModule());
builder.RegisterType<WorkContextAccessor>().As<IWorkContextAccessor>();
builder.RegisterAutoMocking();
_container = builder.Build();

View File

@@ -101,13 +101,13 @@ namespace Orchard.Tests.Mvc {
});
Assert.That(where, Is.EqualTo("init"));
var async = action.BeginInvoke(null, null);
var asyncResult = action.BeginInvoke(null, null);
Thread.Sleep(75);
Assert.That(where, Is.EqualTo("before"));
readLock.Dispose();
Thread.Sleep(75);
Assert.That(where, Is.EqualTo("after"));
action.EndInvoke(async);
action.EndInvoke(asyncResult);
}
}
}

View File

@@ -36,6 +36,7 @@ namespace Orchard.Tests.Mvc.Routes {
rootBuilder.Register(ctx => _routes);
rootBuilder.RegisterType<ShellRoute>().InstancePerDependency();
rootBuilder.RegisterType<RunningShellTable>().As<IRunningShellTable>().SingleInstance();
rootBuilder.RegisterModule(new WorkContextModule());
rootBuilder.RegisterType<WorkContextAccessor>().As<IWorkContextAccessor>().InstancePerMatchingLifetimeScope("shell");
rootBuilder.RegisterType<HttpContextAccessor>().As<IHttpContextAccessor>();

View File

@@ -12,6 +12,7 @@ namespace Orchard.Tests.Tasks {
public class SweepGeneratorTests : ContainerTestBase {
protected override void Register(ContainerBuilder builder) {
builder.RegisterAutoMocking(MockBehavior.Loose);
builder.RegisterModule(new WorkContextModule());
builder.RegisterType<WorkContextAccessor>().As<IWorkContextAccessor>();
builder.RegisterType<SweepGenerator>();
}

View File

@@ -29,7 +29,7 @@ namespace Orchard.Tests.UI {
throw new NotImplementedException("this test fixture needs to move to modules tests now");
}
protected override void Resolve(IContainer container) {
protected override void Resolve(ILifetimeScope container) {
_workContext = container.Resolve<IWorkContextAccessor>().CreateWorkContextScope().WorkContext;
}

View File

@@ -9,7 +9,7 @@ using Moq;
namespace Orchard.Tests.Utility {
public static class ContainerExtensions {
public static Mock<T> Mock<T>(this IContainer container) where T : class {
public static Mock<T> Mock<T>(this IComponentContext container) where T : class {
return container.Resolve<Mock<T>>();
}

View File

@@ -5,6 +5,58 @@ using Orchard.Utility.Extensions;
namespace Orchard.Tests.Utility.Extensions {
[TestFixture]
public class StringExtensionsTests {
[Test]
public void CamelFriendly_CamelCasedStringMadeFriendly() {
const string aCamel = "aCamel";
Assert.That(aCamel.CamelFriendly(), Is.StringMatching("a Camel"));
}
[Test]
public void CamelFriendly_PascalCasedStringMadeFriendly() {
const string aCamel = "ACamel";
Assert.That(aCamel.CamelFriendly(), Is.StringMatching("A Camel"));
}
[Test]
public void CamelFriendly_LowerCasedStringMadeFriendly() {
const string aCamel = "acamel";
Assert.That(aCamel.CamelFriendly(), Is.StringMatching("acamel"));
}
[Test]
public void CamelFriendly_EmptyStringReturnsEmptyString() {
const string aCamel = "";
Assert.That(aCamel.CamelFriendly(), Is.StringMatching(""));
}
[Test]
public void CamelFriendly_NullValueReturnsEmptyString() {
const string aCamel = null;
Assert.That(aCamel.CamelFriendly(), Is.StringMatching(""));
}
[Test]
public void Ellipsize_LongStringTruncatedToNearestWord() {
const string toEllipsize = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas sed purus quis purus orci aliquam.";
Assert.That(toEllipsize.Ellipsize(45), Is.StringMatching("Lorem ipsum dolor sit amet, consectetur&#160;&#8230;"));
}
[Test]
public void Ellipsize_ShortStringReturnedAsSame() {
const string toEllipsize = "Lorem ipsum";
Assert.That(toEllipsize.Ellipsize(45), Is.StringMatching("Lorem ipsum"));
}
[Test]
public void Ellipsize_EmptyStringReturnsEmptyString() {
const string toEllipsize = "";
Assert.That(toEllipsize.Ellipsize(45), Is.StringMatching(""));
}
[Test]
public void Ellipsize_NullValueReturnsEmptyString() {
const string toEllipsize = null;
Assert.That(toEllipsize.Ellipsize(45), Is.StringMatching(""));
}
[Test]
public void Ellipsize_CustomEllipsisStringIsUsed() {
const string toEllipsize = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas sed purus quis purus orci aliquam.";
Assert.That(toEllipsize.Ellipsize(45, "........"), Is.StringMatching("Lorem ipsum dolor sit amet, consectetur........"));
}
[Test]
public void HtmlClassify_ValidReallySimpleClassNameReturnsSame() {
const string toClassify = "someclass";
@@ -40,6 +92,17 @@ namespace Orchard.Tests.Utility.Extensions {
const string toClassify = "PascalCased";
Assert.That(toClassify.HtmlClassify(), Is.StringMatching("pascal-cased"));
}
[Test]
public void HtmlClassify_EmptyStringReturnsEmptyString() {
const string toClassify = "";
Assert.That(toClassify.HtmlClassify(), Is.StringMatching(""));
}
[Test]
public void HtmlClassify_NullValueReturnsEmptyString() {
const string toClassify = null;
Assert.That(toClassify.HtmlClassify(), Is.StringMatching(""));
}
[Test]
public void OrDefault_ReturnsDefaultForNull() {
const string s = null;
@@ -47,15 +110,61 @@ namespace Orchard.Tests.Utility.Extensions {
Assert.That(s.OrDefault(def).Text, Is.SameAs("test"));
}
[Test]
public void OrDefault_ReturnsDefault() {
public void OrDefault_ReturnsDefaultIfEmpty() {
var def = new LocalizedString("test");
Assert.That("".OrDefault(def).Text, Is.SameAs("test"));
}
[Test]
public void OrDefault_ReturnsDefaultIfNull() {
var def = new LocalizedString("test");
Assert.That(((string)null).OrDefault(def).Text, Is.SameAs("test"));
}
[Test]
public void OrDefault_ReturnsString() {
var def = new LocalizedString("test");
Assert.That("bar".OrDefault(def).Text, Is.SameAs("bar"));
}
[Test]
public void RemoveTags_StringWithNoTagsReturnsSame() {
const string fullOfTags = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas sed purus quis purus orci aliquam.";
Assert.That(fullOfTags.RemoveTags(), Is.StringMatching("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas sed purus quis purus orci aliquam."));
}
[Test]
public void RemoveTags_SimpleWellFormedTagsAreRemoved() {
const string fullOfTags = @"<p><em>Lorem ipsum</em> dolor sit amet, consectetur <a href=""#"">adipiscing</a> elit. Maecenas sed purus quis purus orci aliquam.</p>";
Assert.That(fullOfTags.RemoveTags(), Is.StringMatching("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas sed purus quis purus orci aliquam."));
}
[Test]
public void RemoveTags_EmptyStringReturnsEmptyString() {
const string fullOfTags = "";
Assert.That(fullOfTags.RemoveTags(), Is.StringMatching(""));
}
[Test]
public void RemoveTags_NullValueReturnsEmptyString() {
const string fullOfTags = null;
Assert.That(fullOfTags.RemoveTags(), Is.StringMatching(""));
}
[Test]
public void ReplaceNewLinesWith_ReplaceCRLFWithHtmlBR() {
const string lotsOfLineFeeds = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.\r\nMaecenas sed purus quis purus orci aliquam.";
Assert.That(lotsOfLineFeeds.ReplaceNewLinesWith("<br />"), Is.StringMatching("Lorem ipsum dolor sit amet, consectetur adipiscing elit.<br />Maecenas sed purus quis purus orci aliquam."));
}
[Test]
public void ReplaceNewLinesWith_ReplaceCRLFWithHtmlPsAndCRLF() {
const string lotsOfLineFeeds = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.\r\nMaecenas sed purus quis purus orci aliquam.";
Assert.That(lotsOfLineFeeds.ReplaceNewLinesWith(@"</p>$1<p>"), Is.StringMatching("Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>\r\n<p>Maecenas sed purus quis purus orci aliquam."));
}
[Test]
public void ReplaceNewLinesWith_EmptyStringReturnsEmptyString() {
const string lotsOfLineFeeds = "";
Assert.That(lotsOfLineFeeds.ReplaceNewLinesWith("<br />"), Is.StringMatching(""));
}
[Test]
public void ReplaceNewLinesWith_NullValueReturnsEmptyString() {
const string lotsOfLineFeeds = null;
Assert.That(lotsOfLineFeeds.ReplaceNewLinesWith("<br />"), Is.StringMatching(""));
}
}
}

View File

@@ -45,7 +45,9 @@ namespace Orchard.Core.Common.Handlers {
OnVersioned<ContentPart<CommonPartVersionRecord>>(AssignVersioningDates);
OnPublishing<CommonPart>(AssignPublishingDates);
OnUnpublishing<CommonPart>(AssignPublishingDates);
OnPublishing<ContentPart<CommonPartVersionRecord>>(AssignPublishingDates);
OnUnpublishing<ContentPart<CommonPartVersionRecord>>(AssignPublishingDates);
OnIndexing<CommonPart>((context, commonPart) => context.DocumentIndex
.Add("type", commonPart.ContentItem.ContentType).Store()

View File

@@ -1,7 +0,0 @@
using Orchard.Core.Common.Fields;
namespace Orchard.Core.Common.ViewModels {
public class TextContentFieldDisplayViewModel {
public TextField Text { get; set; }
}
}

View File

@@ -1,14 +0,0 @@
using System.ComponentModel.DataAnnotations;
using Orchard.Core.Common.Fields;
namespace Orchard.Core.Common.ViewModels {
public class TextContentFieldEditorViewModel {
public TextField TextField { get; set; }
[Required]
public string Text {
get { return TextField.Value; }
set { TextField.Value = value; }
}
}
}

View File

@@ -1,5 +1,8 @@
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
</httpHandlers>

View File

@@ -7,20 +7,14 @@ using Orchard.ContentManagement.Drivers;
using Orchard.Core.Containers.Models;
using Orchard.Core.Containers.ViewModels;
using Orchard.Core.Routable.Models;
using Orchard.Core.Routable.Services;
using Orchard.Localization;
using Orchard.UI.Notify;
namespace Orchard.Core.Containers.Drivers {
public class ContainablePartDriver : ContentPartDriver<ContainablePart> {
private readonly IContentManager _contentManager;
private readonly IRoutableService _routableService;
private readonly IOrchardServices _services;
public ContainablePartDriver(IContentManager contentManager, IRoutableService routableService, IOrchardServices services) {
public ContainablePartDriver(IContentManager contentManager) {
_contentManager = contentManager;
_routableService = routableService;
_services = services;
T = NullLocalizer.Instance;
}

View File

@@ -1,30 +0,0 @@
using Orchard.ContentManagement;
using Orchard.ContentManagement.Drivers;
using Orchard.ContentManagement.Handlers;
using Orchard.Core.Containers.Models;
using Orchard.Data;
namespace Orchard.Core.Containers.Drivers {
public class ContainerCustomPartDriver : ContentPartDriver<ContainerCustomPart> {
protected override DriverResult Editor(ContainerCustomPart part, dynamic shapeHelper) {
return Editor(part, null, shapeHelper);
}
protected override DriverResult Editor(ContainerCustomPart part, IUpdateModel updater, dynamic shapeHelper) {
return ContentShape(
"Parts_ContainerCustom_Edit",
() => {
if (updater != null)
updater.TryUpdateModel(part, "ContainerCustom", null, null);
return shapeHelper.EditorTemplate(TemplateName: "ContainerCustom", Model: part, Prefix: "ContainerCustom");
});
}
}
public class ContainerCustomPartHandler : ContentHandler {
public ContainerCustomPartHandler(IRepository<ContainerCustomPartRecord> repository) {
Filters.Add(StorageFilter.For(repository));
}
}
}

View File

@@ -1,17 +1,50 @@
using Orchard.ContentManagement;
using System.Linq;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Drivers;
using Orchard.ContentManagement.Handlers;
using Orchard.ContentManagement.MetaData;
using Orchard.Core.Common.Models;
using Orchard.Core.Containers.Models;
using Orchard.Core.Containers.Settings;
using Orchard.Data;
using Orchard.Localization;
using Orchard.UI.Notify;
namespace Orchard.Core.Containers.Drivers {
public class ContainerPartDriver : ContentPartDriver<ContainerPart> {
private readonly IContentDefinitionManager _contentDefinitionManager;
public ContainerPartDriver(IContentDefinitionManager contentDefinitionManager, IOrchardServices orchardServices) {
_contentDefinitionManager = contentDefinitionManager;
Services = orchardServices;
T = NullLocalizer.Instance;
}
public IOrchardServices Services { get; private set; }
public Localizer T { get; set; }
protected override DriverResult Display(ContainerPart part, string displayType, dynamic shapeHelper) {
return Combined(
ContentShape("Parts_Container_Contained",
() => shapeHelper.Parts_Container_Contained(ContentPart: part)),
ContentShape("Parts_Container_Contained_Summary",
() => shapeHelper.Parts_Container_Contained_Summary(ContentPart: part)),
ContentShape("Parts_Container_Contained_SummaryAdmin",
() => shapeHelper.Parts_Container_Contained_SummaryAdmin(ContentPart: part))
);
}
protected override DriverResult Editor(ContainerPart part, dynamic shapeHelper) {
// if there are no containable items then show a nice little warning
if (!_contentDefinitionManager.ListTypeDefinitions()
.Where(typeDefinition => typeDefinition.Parts.Any(partDefinition => partDefinition.PartDefinition.Name == "ContainablePart")).Any()) {
Services.Notifier.Warning(T("There are no content types in the system with a Containable part attached. Consider adding a Containable part to some content type, existing or new, in order to relate items to this (Container enabled) item."));
}
return Editor(part, null, shapeHelper);
}
protected override DriverResult Editor(ContainerPart part, ContentManagement.IUpdateModel updater, dynamic shapeHelper) {
protected override DriverResult Editor(ContainerPart part, IUpdateModel updater, dynamic shapeHelper) {
return ContentShape(
"Parts_Container_Edit",
() => {
@@ -24,7 +57,7 @@ namespace Orchard.Core.Containers.Drivers {
}
public class ContainerPartHandler : ContentHandler {
public ContainerPartHandler(IRepository<ContainerPartRecord> repository, IOrchardServices orchardServices) {
public ContainerPartHandler(IRepository<ContainerPartRecord> repository) {
Filters.Add(StorageFilter.For(repository));
OnInitializing<ContainerPart>((context, part) => {
part.Record.PageSize = part.Settings.GetModel<ContainerTypePartSettings>().PageSizeDefault

View File

@@ -86,7 +86,7 @@ namespace Orchard.Core.Containers.Drivers {
part.Record.PageSize = 5;
part.Record.OrderByProperty = part.Is<CommonPart>() ? "CommonPart.PublishedUtc" : "";
part.Record.OrderByDirection = (int)OrderByDirection.Descending;
part.Record.FilterByProperty = "ContainerCustomPart.CustomOne";
part.Record.FilterByProperty = "CustomPropertiesPart.CustomOne";
part.Record.FilterByOperator = "=";
});
}

View File

@@ -0,0 +1,30 @@
using Orchard.ContentManagement;
using Orchard.ContentManagement.Drivers;
using Orchard.ContentManagement.Handlers;
using Orchard.Core.Containers.Models;
using Orchard.Data;
namespace Orchard.Core.Containers.Drivers {
public class CustomPropertiesPartDriver : ContentPartDriver<CustomPropertiesPart> {
protected override DriverResult Editor(CustomPropertiesPart part, dynamic shapeHelper) {
return Editor(part, null, shapeHelper);
}
protected override DriverResult Editor(CustomPropertiesPart part, IUpdateModel updater, dynamic shapeHelper) {
return ContentShape(
"Parts_CustomProperties_Edit",
() => {
if (updater != null)
updater.TryUpdateModel(part, "CustomProperties", null, null);
return shapeHelper.EditorTemplate(TemplateName: "CustomProperties", Model: part, Prefix: "CustomProperties");
});
}
}
public class CustomPropertiesPartHandler : ContentHandler {
public CustomPropertiesPartHandler(IRepository<CustomPropertiesPartRecord> repository) {
Filters.Add(StorageFilter.For(repository));
}
}
}

View File

@@ -21,20 +21,20 @@ namespace Orchard.Core.Containers.Extensions
? query.OrderByDescending<RoutePartRecord, string>(record => record.Slug)
: query.OrderBy<RoutePartRecord, string>(record => record.Slug);
break;
case "ContainerCustomPart.CustomOne":
case "CustomPropertiesPart.CustomOne":
query = descendingOrder
? query.OrderByDescending<ContainerCustomPartRecord, string>(record => record.CustomOne)
: query.OrderBy<ContainerCustomPartRecord, string>(record => record.CustomOne);
? query.OrderByDescending<CustomPropertiesPartRecord, string>(record => record.CustomOne)
: query.OrderBy<CustomPropertiesPartRecord, string>(record => record.CustomOne);
break;
case "ContainerCustomPart.CustomTwo":
case "CustomPropertiesPart.CustomTwo":
query = descendingOrder
? query.OrderByDescending<ContainerCustomPartRecord, string>(record => record.CustomTwo)
: query.OrderBy<ContainerCustomPartRecord, string>(record => record.CustomTwo);
? query.OrderByDescending<CustomPropertiesPartRecord, string>(record => record.CustomTwo)
: query.OrderBy<CustomPropertiesPartRecord, string>(record => record.CustomTwo);
break;
case "ContainerCustomPart.CustomThree":
case "CustomPropertiesPart.CustomThree":
query = descendingOrder
? query.OrderByDescending<ContainerCustomPartRecord, string>(record => record.CustomThree)
: query.OrderBy<ContainerCustomPartRecord, string>(record => record.CustomThree);
? query.OrderByDescending<CustomPropertiesPartRecord, string>(record => record.CustomThree)
: query.OrderBy<CustomPropertiesPartRecord, string>(record => record.CustomThree);
break;
default: // "CommonPart.PublishedUtc"
query = descendingOrder
@@ -69,18 +69,18 @@ namespace Orchard.Core.Containers.Extensions
{"CommonPart.PublishedUtc|=", new Func<IContentQuery<ContentItem>, string, IContentQuery<ContentItem>>((q, s) => q.Where<CommonPartRecord>(r => r.PublishedUtc == DateTime.Parse(s)))}, // todo: (heskew) not practical as is. needs some sense of precision....
{"CommonPart.PublishedUtc|^=", new Func<IContentQuery<ContentItem>, string, IContentQuery<ContentItem>>((q, s) => q.Where<CommonPartRecord>(r => true /* can't modified PublishedUtc for partial comparisons */))},
// todo: (hesekw) this could benefit from a better filter implementation as this is currently very limited in functionality and I have no idea how the custom parts will be used by folks
{"ContainerCustomPart.CustomOne|<", new Func<IContentQuery<ContentItem>, string, IContentQuery<ContentItem>>((q, s) => q.Where<ContainerCustomPartRecord>(r => true /* CompareTo is not implemented - r.CustomOne.CompareTo(s) == -1*/))},
{"ContainerCustomPart.CustomOne|>", new Func<IContentQuery<ContentItem>, string, IContentQuery<ContentItem>>((q, s) => q.Where<ContainerCustomPartRecord>(r => true /* CompareTo is not implemented - r.CustomOne.CompareTo(s) == 1*/))},
{"ContainerCustomPart.CustomOne|=", new Func<IContentQuery<ContentItem>, string, IContentQuery<ContentItem>>((q, s) => q.Where<ContainerCustomPartRecord>(r => r.CustomOne.Equals(s, StringComparison.OrdinalIgnoreCase)))},
{"ContainerCustomPart.CustomOne|^=", new Func<IContentQuery<ContentItem>, string, IContentQuery<ContentItem>>((q, s) => q.Where<ContainerCustomPartRecord>(r => r.CustomOne.StartsWith(s, StringComparison.OrdinalIgnoreCase)))},
{"ContainerCustomPart.CustomTwo|<", new Func<IContentQuery<ContentItem>, string, IContentQuery<ContentItem>>((q, s) => q.Where<ContainerCustomPartRecord>(r => true /* CompareTo is not implemented - r.CustomTwo.CompareTo(s) == -1*/))},
{"ContainerCustomPart.CustomTwo|>", new Func<IContentQuery<ContentItem>, string, IContentQuery<ContentItem>>((q, s) => q.Where<ContainerCustomPartRecord>(r => true /* CompareTo is not implemented - r.CustomTwo.CompareTo(s) == 1*/))},
{"ContainerCustomPart.CustomTwo|=", new Func<IContentQuery<ContentItem>, string, IContentQuery<ContentItem>>((q, s) => q.Where<ContainerCustomPartRecord>(r => r.CustomTwo.Equals(s, StringComparison.OrdinalIgnoreCase)))},
{"ContainerCustomPart.CustomTwo|^=", new Func<IContentQuery<ContentItem>, string, IContentQuery<ContentItem>>((q, s) => q.Where<ContainerCustomPartRecord>(r => r.CustomTwo.StartsWith(s, StringComparison.OrdinalIgnoreCase)))},
{"ContainerCustomPart.CustomThree|<", new Func<IContentQuery<ContentItem>, string, IContentQuery<ContentItem>>((q, s) => q.Where<ContainerCustomPartRecord>(r => true /* CompareTo is not implemented - r.CustomThree.CompareTo(s) == -1*/))},
{"ContainerCustomPart.CustomThree|>", new Func<IContentQuery<ContentItem>, string, IContentQuery<ContentItem>>((q, s) => q.Where<ContainerCustomPartRecord>(r => true /* CompareTo is not implemented - r.CustomThree.CompareTo(s) == 1*/))},
{"ContainerCustomPart.CustomThree|=", new Func<IContentQuery<ContentItem>, string, IContentQuery<ContentItem>>((q, s) => q.Where<ContainerCustomPartRecord>(r => r.CustomThree.Equals(s, StringComparison.OrdinalIgnoreCase)))},
{"ContainerCustomPart.CustomThree|^=", new Func<IContentQuery<ContentItem>, string, IContentQuery<ContentItem>>((q, s) => q.Where<ContainerCustomPartRecord>(r => r.CustomThree.StartsWith(s, StringComparison.OrdinalIgnoreCase)))},
{"CustomPropertiesPart.CustomOne|<", new Func<IContentQuery<ContentItem>, string, IContentQuery<ContentItem>>((q, s) => q.Where<CustomPropertiesPartRecord>(r => true /* CompareTo is not implemented - r.CustomOne.CompareTo(s) == -1*/))},
{"CustomPropertiesPart.CustomOne|>", new Func<IContentQuery<ContentItem>, string, IContentQuery<ContentItem>>((q, s) => q.Where<CustomPropertiesPartRecord>(r => true /* CompareTo is not implemented - r.CustomOne.CompareTo(s) == 1*/))},
{"CustomPropertiesPart.CustomOne|=", new Func<IContentQuery<ContentItem>, string, IContentQuery<ContentItem>>((q, s) => q.Where<CustomPropertiesPartRecord>(r => r.CustomOne.Equals(s, StringComparison.OrdinalIgnoreCase)))},
{"CustomPropertiesPart.CustomOne|^=", new Func<IContentQuery<ContentItem>, string, IContentQuery<ContentItem>>((q, s) => q.Where<CustomPropertiesPartRecord>(r => r.CustomOne.StartsWith(s, StringComparison.OrdinalIgnoreCase)))},
{"CustomPropertiesPart.CustomTwo|<", new Func<IContentQuery<ContentItem>, string, IContentQuery<ContentItem>>((q, s) => q.Where<CustomPropertiesPartRecord>(r => true /* CompareTo is not implemented - r.CustomTwo.CompareTo(s) == -1*/))},
{"CustomPropertiesPart.CustomTwo|>", new Func<IContentQuery<ContentItem>, string, IContentQuery<ContentItem>>((q, s) => q.Where<CustomPropertiesPartRecord>(r => true /* CompareTo is not implemented - r.CustomTwo.CompareTo(s) == 1*/))},
{"CustomPropertiesPart.CustomTwo|=", new Func<IContentQuery<ContentItem>, string, IContentQuery<ContentItem>>((q, s) => q.Where<CustomPropertiesPartRecord>(r => r.CustomTwo.Equals(s, StringComparison.OrdinalIgnoreCase)))},
{"CustomPropertiesPart.CustomTwo|^=", new Func<IContentQuery<ContentItem>, string, IContentQuery<ContentItem>>((q, s) => q.Where<CustomPropertiesPartRecord>(r => r.CustomTwo.StartsWith(s, StringComparison.OrdinalIgnoreCase)))},
{"CustomPropertiesPart.CustomThree|<", new Func<IContentQuery<ContentItem>, string, IContentQuery<ContentItem>>((q, s) => q.Where<CustomPropertiesPartRecord>(r => true /* CompareTo is not implemented - r.CustomThree.CompareTo(s) == -1*/))},
{"CustomPropertiesPart.CustomThree|>", new Func<IContentQuery<ContentItem>, string, IContentQuery<ContentItem>>((q, s) => q.Where<CustomPropertiesPartRecord>(r => true /* CompareTo is not implemented - r.CustomThree.CompareTo(s) == 1*/))},
{"CustomPropertiesPart.CustomThree|=", new Func<IContentQuery<ContentItem>, string, IContentQuery<ContentItem>>((q, s) => q.Where<CustomPropertiesPartRecord>(r => r.CustomThree.Equals(s, StringComparison.OrdinalIgnoreCase)))},
{"CustomPropertiesPart.CustomThree|^=", new Func<IContentQuery<ContentItem>, string, IContentQuery<ContentItem>>((q, s) => q.Where<CustomPropertiesPartRecord>(r => r.CustomThree.StartsWith(s, StringComparison.OrdinalIgnoreCase)))},
};
}
}

View File

@@ -25,7 +25,7 @@ namespace Orchard.Core.Containers {
.Column<string>("FilterByOperator")
.Column<string>("FilterByValue"));
SchemaBuilder.CreateTable("ContainerCustomPartRecord",
SchemaBuilder.CreateTable("CustomPropertiesPartRecord",
table => table
.ContentPartRecord()
.Column<string>("CustomOne")
@@ -41,7 +41,7 @@ namespace Orchard.Core.Containers {
ContentDefinitionManager.AlterPartDefinition("ContainerPart", builder => builder.Attachable());
ContentDefinitionManager.AlterPartDefinition("ContainablePart", builder => builder.Attachable());
ContentDefinitionManager.AlterPartDefinition("ContainerCustomPart", builder => builder.Attachable());
ContentDefinitionManager.AlterPartDefinition("CustomPropertiesPart", builder => builder.Attachable());
return 1;
}

View File

@@ -2,10 +2,10 @@
using Orchard.ContentManagement.Records;
namespace Orchard.Core.Containers.Models {
public class ContainerCustomPart : ContentPart<ContainerCustomPartRecord> {
public class CustomPropertiesPart : ContentPart<CustomPropertiesPartRecord> {
}
public class ContainerCustomPartRecord : ContentPartRecord {
public class CustomPropertiesPartRecord : ContentPartRecord {
public virtual string CustomOne { get; set; }
public virtual string CustomTwo { get; set; }
public virtual string CustomThree { get; set; }

View File

@@ -1,8 +1,17 @@
<Placement>
<!-- available display shapes -->
<!--
Parts_Container_Contained
Parts_Container_Contained_Summary
Parts_Container_Contained_SummaryAdmin
-->
<Place Parts_Containable_Edit="Content:before.3"/>
<Place Parts_Container_Edit="Content:5"/>
<Place Parts_ContainerCustom_Edit="Content:5"/>
<Place Parts_CustomProperties_Edit="Content:5"/>
<Place Parts_ContainerWidget_Edit="Content:5"/>
<Place Parts_Container_SiteSettings="Content:10"/>
<Place Parts_ContainerWidget="Content"/>
<Match DisplayType="SummaryAdmin">
<Place Parts_Container_Contained_SummaryAdmin="Actions:10"/>
</Match>
</Placement>

View File

@@ -6,9 +6,9 @@
@Html.SelectOption(Model.Record.OrderByProperty, "CommonPart.PublishedUtc", T("Date Published").Text)
@Html.SelectOption(Model.Record.OrderByProperty, "RoutePart.Title", T("Title").Text)
@Html.SelectOption(Model.Record.OrderByProperty, "RoutePart.Slug", T("Slug").Text)
@Html.SelectOption(Model.Record.OrderByProperty, "ContainerCustomPart.CustomOne", T("Custom 1").Text)
@Html.SelectOption(Model.Record.OrderByProperty, "ContainerCustomPart.CustomTwo", T("Custom 2").Text)
@Html.SelectOption(Model.Record.OrderByProperty, "ContainerCustomPart.CustomThree", T("Custom 3").Text)
@Html.SelectOption(Model.Record.OrderByProperty, "CustomPropertiesPart.CustomOne", T("Custom 1").Text)
@Html.SelectOption(Model.Record.OrderByProperty, "CustomPropertiesPart.CustomTwo", T("Custom 2").Text)
@Html.SelectOption(Model.Record.OrderByProperty, "CustomPropertiesPart.CustomThree", T("Custom 3").Text)
</select>
<select id="@Html.FieldIdFor(m => m.Record.OrderByDirection)" name="@Html.FieldNameFor(m => m.Record.OrderByDirection)">
@Html.SelectOption(Model.Record.OrderByDirection, (int)OrderByDirection.Ascending, T("Ascending").Text)

View File

@@ -19,9 +19,9 @@
@Html.SelectOption(Model.Part.Record.OrderByProperty, "CommonPart.PublishedUtc", T("Date Published").Text)
@Html.SelectOption(Model.Part.Record.OrderByProperty, "RoutePart.Title", T("Title").Text)
@Html.SelectOption(Model.Part.Record.OrderByProperty, "RoutePart.Slug", T("Slug").Text)
@Html.SelectOption(Model.Part.Record.OrderByProperty, "ContainerCustomPart.CustomOne", T("Custom 1").Text)
@Html.SelectOption(Model.Part.Record.OrderByProperty, "ContainerCustomPart.CustomTwo", T("Custom 2").Text)
@Html.SelectOption(Model.Part.Record.OrderByProperty, "ContainerCustomPart.CustomThree", T("Custom 3").Text)
@Html.SelectOption(Model.Part.Record.OrderByProperty, "CustomPropertiesPart.CustomOne", T("Custom 1").Text)
@Html.SelectOption(Model.Part.Record.OrderByProperty, "CustomPropertiesPart.CustomTwo", T("Custom 2").Text)
@Html.SelectOption(Model.Part.Record.OrderByProperty, "CustomPropertiesPart.CustomThree", T("Custom 3").Text)
</select>
<select title="@T("Order direction")" id="@Html.FieldIdFor(m => m.Part.Record.OrderByDirection)" name="@Html.FieldNameFor(m => m.Part.Record.OrderByDirection)">
@Html.SelectOption(Model.Part.Record.OrderByDirection, (int)OrderByDirection.Ascending, T("Ascending").Text)
@@ -39,9 +39,9 @@
@Html.SelectOption(Model.Part.Record.FilterByProperty, "CommonPart.PublishedUtc", T("Date Published").Text)
@Html.SelectOption(Model.Part.Record.FilterByProperty, "RoutePart.Title", T("Title").Text)
@Html.SelectOption(Model.Part.Record.FilterByProperty, "RoutePart.Slug", T("Slug").Text)
@Html.SelectOption(Model.Part.Record.FilterByProperty, "ContainerCustomPart.CustomOne", T("Custom 1").Text)
@Html.SelectOption(Model.Part.Record.FilterByProperty, "ContainerCustomPart.CustomTwo", T("Custom 2").Text)
@Html.SelectOption(Model.Part.Record.FilterByProperty, "ContainerCustomPart.CustomThree", T("Custom 3").Text)
@Html.SelectOption(Model.Part.Record.FilterByProperty, "CustomPropertiesPart.CustomOne", T("Custom 1").Text)
@Html.SelectOption(Model.Part.Record.FilterByProperty, "CustomPropertiesPart.CustomTwo", T("Custom 2").Text)
@Html.SelectOption(Model.Part.Record.FilterByProperty, "CustomPropertiesPart.CustomThree", T("Custom 3").Text)
</select>
<select title="@T("Filter operator")" id="@Html.FieldIdFor(m => m.Part.Record.FilterByOperator)" name="@Html.FieldNameFor(m => m.Part.Record.FilterByOperator)">
@Html.SelectOption(Model.Part.Record.FilterByOperator, "=", T("is equal to").Text)

View File

@@ -1,4 +1,4 @@
@model Orchard.Core.Containers.Models.ContainerCustomPart
@model Orchard.Core.Containers.Models.CustomPropertiesPart
<fieldset>
@Html.LabelFor(m => m.Record.CustomOne, T("Custom One"))
@Html.EditorFor(m => m.Record.CustomOne)

View File

@@ -0,0 +1,9 @@
@using Orchard.ContentManagement;
@using Orchard.Core.Containers.Models;
@using Orchard.Utility.Extensions;
@{
ContentPart contentPart = Model.ContentPart;
}
@if (contentPart.Is<ContainerPart>()) {
@Html.Link(T("Contained Items").Text, Url.Action("List", "Admin", new { area = "Contents", containerId = contentPart.Id }))@T(" | ")
}

View File

@@ -8,7 +8,6 @@ using Orchard.ContentManagement;
using Orchard.ContentManagement.Aspects;
using Orchard.ContentManagement.MetaData;
using Orchard.ContentManagement.MetaData.Models;
using Orchard.ContentManagement.Records;
using Orchard.Core.Common.Models;
using Orchard.Core.Contents.Settings;
using Orchard.Core.Contents.ViewModels;
@@ -62,9 +61,10 @@ namespace Orchard.Core.Contents.Controllers {
: contentTypeDefinition.Name;
query = query.ForType(model.TypeName);
}
if (model.ContainerId != null)
if (model.ContainerId != null) {
query = query.Join<CommonPartRecord>().Where(cr => cr.Container.Id == model.ContainerId);
}
switch (model.Options.OrderBy) {
case ContentsOrder.Modified:

View File

@@ -2,6 +2,7 @@
<!-- available display shapes -->
<!--
Parts_Contents_Publish
Parts_Contents_Publish_Summary
Parts_Contents_Publish_SummaryAdmin
-->
<!-- edit "shape" -->

View File

@@ -5,8 +5,6 @@ using Orchard.Mvc.Routes;
namespace Orchard.Core.Contents {
public class Routes : IRouteProvider {
#region IRouteProvider Members
public void GetRoutes(ICollection<RouteDescriptor> routes) {
foreach (RouteDescriptor routeDescriptor in GetRoutes()) {
routes.Add(routeDescriptor);
@@ -24,7 +22,28 @@ namespace Orchard.Core.Contents {
{"controller", "Admin"},
{"action", "List"}
},
new RouteValueDictionary(),
new RouteValueDictionary {
{"id", @"\w+"},
{"containerId", @"\d+"}
},
new RouteValueDictionary {
{"area", "Contents"}
},
new MvcRouteHandler())
},
new RouteDescriptor {
Priority = 5,
Route = new Route(
"Admin/Contents/List/InContainer/{containerId}",
new RouteValueDictionary {
{"area", "Contents"},
{"controller", "Admin"},
{"action", "List"},
{"id", ""}
},
new RouteValueDictionary{
{"containerId", @"\d+"}
},
new RouteValueDictionary {
{"area", "Contents"}
},
@@ -32,7 +51,5 @@ namespace Orchard.Core.Contents {
}
};
}
#endregion
}
}

View File

@@ -1,5 +1,8 @@
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
</httpHandlers>

View File

@@ -1,5 +1,8 @@
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
</httpHandlers>

View File

@@ -1,5 +1,8 @@
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
</httpHandlers>

View File

@@ -71,7 +71,7 @@
<Compile Include="Common\Drivers\TextFieldDriver.cs" />
<Compile Include="Containers\ContainersPathConstraint.cs" />
<Compile Include="Containers\Drivers\ContainerWidgetPartDriver.cs" />
<Compile Include="Containers\Drivers\ContainerCustomPartDriver.cs" />
<Compile Include="Containers\Drivers\CustomPropertiesDriver.cs" />
<Compile Include="Containers\Extensions\ContentQueryExtensions.cs" />
<Compile Include="Containers\Migrations.cs" />
<Compile Include="Containers\Models\ContainablePart.cs" />
@@ -79,7 +79,7 @@
<Compile Include="Common\Shapes.cs" />
<Compile Include="Common\Fields\TextField.cs" />
<Compile Include="Containers\Models\ContainerWidgetPart.cs" />
<Compile Include="Containers\Models\ContainerCustomPart.cs" />
<Compile Include="Containers\Models\CustomPropertiesPart.cs" />
<Compile Include="Containers\Models\OrderByDirection.cs" />
<Compile Include="Containers\Routes.cs" />
<Compile Include="Containers\Services\ContainersPathConstraintUpdater.cs" />
@@ -92,8 +92,6 @@
<Compile Include="Common\Services\CommonService.cs" />
<Compile Include="Common\Settings\BodySettings.cs" />
<Compile Include="Common\ViewModels\ContainerEditorViewModel.cs" />
<Compile Include="Common\ViewModels\TextContentFieldDisplayViewModel.cs" />
<Compile Include="Common\ViewModels\TextContentFieldEditorViewModel.cs" />
<Compile Include="Contents\Controllers\ItemController.cs" />
<Compile Include="Contents\Drivers\ContentsDriver.cs" />
<Compile Include="Contents\DynamicPermissions.cs" />
@@ -366,10 +364,13 @@
<Content Include="Containers\Views\DefinitionTemplates\ContainerTypePartSettings.cshtml" />
<Content Include="Containers\Views\EditorTemplates\Containable.cshtml" />
<Content Include="Containers\Views\Parts\ContainerWidget.cshtml" />
<Content Include="Containers\Views\EditorTemplates\ContainerCustom.cshtml" />
<Content Include="Containers\Views\EditorTemplates\CustomProperties.cshtml" />
<Content Include="Routable\Views\Parts\RoutableTitle_Summary.cshtml" />
<Content Include="Routable\Views\Parts\RoutableTitle_SummaryAdmin.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Include="Containers\Views\Parts\Container.Contained.SummaryAdmin.cshtml" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.

View File

@@ -1,5 +1,8 @@
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
</httpHandlers>

View File

@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using Orchard.ContentManagement;
@@ -8,6 +9,7 @@ using Orchard.Core.Routable.Services;
using Orchard.Data;
using Orchard.DisplayManagement;
using Orchard.Localization;
using Orchard.Services;
using Orchard.Themes;
namespace Orchard.Core.Routable.Controllers {
@@ -16,25 +18,33 @@ namespace Orchard.Core.Routable.Controllers {
private readonly IContentManager _contentManager;
private readonly ITransactionManager _transactionManager;
private readonly IRoutablePathConstraint _routablePathConstraint;
private readonly IWorkContextAccessor _workContextAccessor;
private readonly IHomePageProvider _routableHomePageProvider;
public ItemController(
IContentManager contentManager,
ITransactionManager transactionManager,
IRoutablePathConstraint routablePathConstraint,
IShapeFactory shapeFactory) {
IRoutablePathConstraint routablePathConstraint,
IShapeFactory shapeFactory,
IWorkContextAccessor workContextAccessor,
IEnumerable<IHomePageProvider> homePageProviders) {
_contentManager = contentManager;
_transactionManager = transactionManager;
_routablePathConstraint = routablePathConstraint;
_workContextAccessor = workContextAccessor;
_routableHomePageProvider = homePageProviders.SingleOrDefault(p => p.GetProviderName() == RoutableHomePageProvider.Name);
Shape = shapeFactory;
T = NullLocalizer.Instance;
}
public Localizer T { get; set; }
dynamic Shape { get; set; }
[Themed]
public ActionResult Display(string path) {
var matchedPath = _routablePathConstraint.FindPath(path);
if (string.IsNullOrEmpty(matchedPath)) {
throw new ApplicationException("404 - should not have passed path constraint");
if (matchedPath == null) {
throw new ApplicationException(T("404 - should not have passed path constraint").Text);
}
var hits = _contentManager
@@ -42,10 +52,10 @@ namespace Orchard.Core.Routable.Controllers {
.Where(r => r.Path == matchedPath)
.Slice(0, 2);
if (hits.Count() == 0) {
throw new ApplicationException("404 - should not have passed path constraint");
throw new ApplicationException(T("404 - should not have passed path constraint").Text);
}
if (hits.Count() != 1) {
throw new ApplicationException("Ambiguous content");
throw new ApplicationException(T("Ambiguous content").Text);
}
dynamic model = _contentManager.BuildDisplay(hits.Single());

View File

@@ -8,17 +8,24 @@ using Orchard.Core.Routable.Models;
using Orchard.Core.Routable.Services;
using Orchard.Core.Routable.ViewModels;
using Orchard.Localization;
using Orchard.Mvc;
using Orchard.Services;
using Orchard.Utility.Extensions;
namespace Orchard.Core.Routable.Drivers {
public class RoutePartDriver : ContentPartDriver<RoutePart> {
private readonly IOrchardServices _services;
private readonly IRoutableService _routableService;
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly IHomePageProvider _routableHomePageProvider;
public RoutePartDriver(IOrchardServices services, IRoutableService routableService, IEnumerable<IHomePageProvider> homePageProviders) {
public RoutePartDriver(IOrchardServices services,
IRoutableService routableService,
IEnumerable<IHomePageProvider> homePageProviders,
IHttpContextAccessor httpContextAccessor) {
_services = services;
_routableService = routableService;
_httpContextAccessor = httpContextAccessor;
_routableHomePageProvider = homePageProviders.SingleOrDefault(p => p.GetProviderName() == RoutableHomePageProvider.Name);
T = NullLocalizer.Instance;
}
@@ -59,12 +66,11 @@ namespace Orchard.Core.Routable.Drivers {
ContainerId = GetContainerId(part),
};
var containerPath = part.GetContainerPath();
model.DisplayLeadingPath = !string.IsNullOrWhiteSpace(containerPath)
? string.Format("{0}/", containerPath)
: "";
var request = _httpContextAccessor.Current().Request;
var containerUrl = new UriBuilder(request.ToRootUrlString()) { Path = (request.ApplicationPath ?? "").TrimEnd('/') + "/" + (part.GetContainerPath() ?? "") };
model.ContainerAbsoluteUrl = containerUrl.Uri.ToString().TrimEnd('/');
model.PromoteToHomePage = model.Id != 0 && part.Path != null && _routableHomePageProvider != null && _services.WorkContext.CurrentSite.HomePage == _routableHomePageProvider.GetSettingValue(model.Id);
model.PromoteToHomePage = model.Id != 0 && _routableHomePageProvider != null && _services.WorkContext.CurrentSite.HomePage == _routableHomePageProvider.GetSettingValue(model.Id);
return ContentShape("Parts_Routable_Edit",
() => shapeHelper.EditorTemplate(TemplateName: TemplateName, Model: model, Prefix: Prefix));
}
@@ -75,6 +81,7 @@ namespace Orchard.Core.Routable.Drivers {
part.Title = model.Title;
part.Slug = model.Slug;
part.PromoteToHomePage = model.PromoteToHomePage;
if ( !_routableService.IsSlugValid(part.Slug) ) {
var slug = (part.Slug ?? String.Empty);
@@ -84,9 +91,6 @@ namespace Orchard.Core.Routable.Drivers {
updater.AddModelError("Routable.Slug", T("Please do not use any of the following characters in your slugs: \":\", \"?\", \"#\", \"[\", \"]\", \"@\", \"!\", \"$\", \"&\", \"'\", \"(\", \")\", \"*\", \"+\", \",\", \";\", \"=\", \", \"<\", \">\". No spaces are allowed (please use dashes or underscores instead)."));
}
if (part.ContentItem.Id != 0 && model.PromoteToHomePage && _routableHomePageProvider != null)
_services.WorkContext.CurrentSite.HomePage = _routableHomePageProvider.GetSettingValue(part.ContentItem.Id);
return Editor(part, shapeHelper);
}
}

View File

@@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Routing;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Handlers;
@@ -6,6 +8,7 @@ using Orchard.Core.Routable.Models;
using Orchard.Core.Routable.Services;
using Orchard.Data;
using Orchard.Localization;
using Orchard.Services;
using Orchard.UI.Notify;
namespace Orchard.Core.Routable.Handlers {
@@ -13,11 +16,24 @@ namespace Orchard.Core.Routable.Handlers {
private readonly IOrchardServices _services;
private readonly IRoutablePathConstraint _routablePathConstraint;
private readonly IRoutableService _routableService;
private readonly IContentManager _contentManager;
private readonly IWorkContextAccessor _workContextAccessor;
private readonly IHomePageProvider _routableHomePageProvider;
public RoutePartHandler(IOrchardServices services, IRepository<RoutePartRecord> repository, IRoutablePathConstraint routablePathConstraint, IRoutableService routableService) {
public RoutePartHandler(
IOrchardServices services,
IRepository<RoutePartRecord> repository,
IRoutablePathConstraint routablePathConstraint,
IRoutableService routableService,
IContentManager contentManager,
IWorkContextAccessor workContextAccessor,
IEnumerable<IHomePageProvider> homePageProviders) {
_services = services;
_routablePathConstraint = routablePathConstraint;
_routableService = routableService;
_contentManager = contentManager;
_workContextAccessor = workContextAccessor;
_routableHomePageProvider = homePageProviders.SingleOrDefault(p => p.GetProviderName() == RoutableHomePageProvider.Name);
T = NullLocalizer.Instance;
Filters.Add(StorageFilter.For(repository));
@@ -33,23 +49,33 @@ namespace Orchard.Core.Routable.Handlers {
OnGetEditorShape<RoutePart>(SetModelProperties);
OnUpdateEditorShape<RoutePart>(SetModelProperties);
OnPublished<RoutePart>((context, route) => {
var path = route.Path;
route.Path = route.GetPathWithSlug(route.Slug);
Action<PublishContentContext, RoutePart> handler = (context, route) => {
FinalizePath(route, context, processSlug);
if (context.PublishingItemVersionRecord != null)
processSlug(route);
if (route.Id != 0 && route.PromoteToHomePage && _routableHomePageProvider != null) {
var homePageSetting = _workContextAccessor.GetContext().CurrentSite.HomePage;
var currentHomePageId = !string.IsNullOrWhiteSpace(homePageSetting)
? _routableHomePageProvider.GetHomePageId(homePageSetting)
: 0;
// if the path has changed by having the slug changed on the way in (e.g. user input) or to avoid conflict
// then update and publish all contained items
if (path != route.Path) {
_routablePathConstraint.RemovePath(path);
if (currentHomePageId != route.Id) {
// reset the path on the current home page
var currentHomePage = _contentManager.Get(currentHomePageId);
if (currentHomePage != null)
FinalizePath(currentHomePage.As<RoutePart>(), context, processSlug);
// set the new home page
_services.WorkContext.CurrentSite.HomePage = _routableHomePageProvider.GetSettingValue(route.ContentItem.Id);
}
// readjust the constraints of the current current home page
_routablePathConstraint.RemovePath(route.Path);
route.Path = "";
_routableService.FixContainedPaths(route);
}
if (!string.IsNullOrWhiteSpace(route.Path))
_routablePathConstraint.AddPath(route.Path);
});
}
};
OnPublished<RoutePart>(handler);
OnUnpublished<RoutePart>(handler);
OnRemoved<RoutePart>((context, route) => {
if (!string.IsNullOrWhiteSpace(route.Path))
@@ -59,6 +85,24 @@ namespace Orchard.Core.Routable.Handlers {
OnIndexing<RoutePart>((context, part) => context.DocumentIndex.Add("title", part.Record.Title).RemoveTags().Analyze());
}
private void FinalizePath(RoutePart route, PublishContentContext context, Action<RoutePart> processSlug) {
var path = route.Path;
route.Path = route.GetPathWithSlug(route.Slug);
if (context.PublishingItemVersionRecord != null)
processSlug(route);
// if the path has changed by having the slug changed on the way in (e.g. user input) or to avoid conflict
// then update and publish all contained items
if (path != route.Path) {
_routablePathConstraint.RemovePath(path);
_routableService.FixContainedPaths(route);
}
if (!string.IsNullOrWhiteSpace(route.Path))
_routablePathConstraint.AddPath(route.Path);
}
private static void SetModelProperties(BuildShapeContext context, RoutePart routable) {
var item = context.Shape;
item.Title = routable.Title;
@@ -70,6 +114,14 @@ namespace Orchard.Core.Routable.Handlers {
}
public class RoutePartHandlerBase : ContentHandlerBase {
private readonly IWorkContextAccessor _workContextAccessor;
private readonly IHomePageProvider _routableHomePageProvider;
public RoutePartHandlerBase(IWorkContextAccessor workContextAccessor, IEnumerable<IHomePageProvider> homePageProviders) {
_workContextAccessor = workContextAccessor;
_routableHomePageProvider = homePageProviders.SingleOrDefault(p => p.GetProviderName() == RoutableHomePageProvider.Name);
}
public override void GetContentItemMetadata(GetContentItemMetadataContext context) {
var routable = context.ContentItem.As<RoutePart>();
@@ -81,11 +133,15 @@ namespace Orchard.Core.Routable.Handlers {
// set the display route values if it hasn't been set or only has been set by the Contents module.
// allows other modules to set their own display. probably not common enough to warrant some priority implemntation
if (context.Metadata.DisplayRouteValues == null || context.Metadata.DisplayRouteValues["Area"] as string == "Contents") {
var itemPath = routable.Id == _routableHomePageProvider.GetHomePageId(_workContextAccessor.GetContext().CurrentSite.HomePage)
? ""
: routable.Path;
context.Metadata.DisplayRouteValues = new RouteValueDictionary {
{"Area", "Routable"},
{"Controller", "Item"},
{"Action", "Display"},
{"path", routable.Path}
{"path", itemPath}
};
}
}

View File

@@ -3,7 +3,6 @@ using Orchard.ContentManagement.Aspects;
namespace Orchard.Core.Routable.Models {
public class RoutePart : ContentPart<RoutePartRecord>, IRoutableAspect {
public string Title {
get { return Record.Title; }
set { Record.Title = value; }
@@ -18,5 +17,7 @@ namespace Orchard.Core.Routable.Models {
get { return Record.Path; }
set { Record.Path = value; }
}
public bool PromoteToHomePage { get; set; }
}
}

View File

@@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
<!-- iis6 - for any request in this location, return via managed static file handler -->

View File

@@ -1,4 +1,5 @@
using System.Web.Mvc;
using System;
using System.Web.Mvc;
using JetBrains.Annotations;
using Orchard.Core.Routable.Models;
using Orchard.DisplayManagement;
@@ -10,24 +11,18 @@ namespace Orchard.Core.Routable.Services {
[UsedImplicitly]
public class RoutableHomePageProvider : IHomePageProvider {
private readonly IContentManager _contentManager;
private readonly IWorkContextAccessor _workContextAccessor;
public const string Name = "RoutableHomePageProvider";
public RoutableHomePageProvider(
IOrchardServices services,
IContentManager contentManager,
IShapeFactory shapeFactory,
IWorkContextAccessor workContextAccessor) {
IShapeFactory shapeFactory) {
_contentManager = contentManager;
_workContextAccessor = workContextAccessor;
Services = services;
T = NullLocalizer.Instance;
Shape = shapeFactory;
T = NullLocalizer.Instance;
}
dynamic Shape { get; set; }
public IOrchardServices Services { get; private set; }
public Localizer T { get; set; }
dynamic Shape { get; set; }
public string GetProviderName() {
return Name;
@@ -37,8 +32,17 @@ namespace Orchard.Core.Routable.Services {
return GetProviderName() + ";" + id;
}
public ActionResult GetHomePage(int itemId) {
var contentItem = _contentManager.Get(itemId, VersionOptions.Published);
public int GetHomePageId(string value) {
int id;
if (string.IsNullOrWhiteSpace(value) || !int.TryParse(value.Substring(Name.Length + 1), out id))
throw new ApplicationException(T("Invalid home page setting value for {0}: {1}", Name, value).Text);
return id;
}
public ActionResult GetHomePage(int id) {
var contentItem = _contentManager.Get(id, VersionOptions.Published);
if (contentItem == null || !contentItem.Is<RoutePart>())
return new HttpNotFoundResult();

View File

@@ -1,5 +1,4 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations;
namespace Orchard.Core.Routable.ViewModels {
public class RoutableEditorViewModel {
@@ -15,6 +14,6 @@ namespace Orchard.Core.Routable.ViewModels {
public int? ContainerId { get; set; }
public bool PromoteToHomePage { get; set; }
public string DisplayLeadingPath { get; set; }
public string ContainerAbsoluteUrl { get; set; }
}
}

View File

@@ -7,7 +7,7 @@
@Html.TextBoxFor(m => m.Title, new { @class = "large text" })
</fieldset>
<fieldset class="permalink">
<label class="sub" for="Slug">@T("Permalink")<br /><span>@Request.ToRootUrlString()/@Model.DisplayLeadingPath</span></label>
<label class="sub" for="Slug">@T("Permalink")<br /><span>@Model.ContainerAbsoluteUrl/</span></label>
<span>@Html.TextBoxFor(m => m.Slug, new { @class = "text" })</span>
<span class="checkbox-and-label">
@Html.EditorFor(m => m.PromoteToHomePage)

View File

@@ -1,5 +1,8 @@
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
</httpHandlers>

View File

@@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
<!-- iis6 - for any request in this location, return via managed static file handler -->

View File

@@ -1,5 +1,8 @@
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
</httpHandlers>

View File

@@ -225,7 +225,14 @@ namespace Orchard.Core.Shapes {
foreach (var context in requiredResources.Where(r =>
(includeLocation.HasValue ? r.Settings.Location == includeLocation.Value : true) &&
(excludeLocation.HasValue ? r.Settings.Location != excludeLocation.Value : true))) {
var condition = context.Settings.Condition;
if (!string.IsNullOrEmpty(condition)) {
html.ViewContext.Writer.WriteLine("<!--[if " + condition + "]>");
}
html.ViewContext.Writer.WriteLine(context.GetTagBuilder(defaultSettings, appPath).ToString(context.Resource.TagRenderMode));
if (!string.IsNullOrEmpty(condition)) {
html.ViewContext.Writer.WriteLine("<![endif]-->");
}
}
}

View File

@@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
<!-- iis6 - for any request in this location, return via managed static file handler -->

View File

@@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
<!-- iis6 - for any request in this location, return via managed static file handler -->

View File

@@ -1,5 +1,8 @@
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
</httpHandlers>

View File

@@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
<!-- iis6 - for any request in this location, return via managed static file handler -->

View File

@@ -7,5 +7,6 @@ OrchardVersion: 0.8.0
Description: The Lucene module enables the site to be indexed using Lucene.NET. The index generated by this module can then be used by the search module to provide an integrated full-text search experience to a web site.
Features:
Lucene:
Name: Lucene
Description: Lucene indexing services.
Category: Search
Category: Search

View File

@@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
<!-- iis6 - for any request in this location, return via managed static file handler -->

View File

@@ -7,6 +7,7 @@ OrchardVersion: 0.8.0
Description: The ArhiveLater module introduces scheduled archiving functionality.
Features:
Orchard.ArchiveLater:
Name: Archive Later
Description: Scheduled archiving.
Category: Content
Dependencies: Common, Scheduling, Orchard.jQuery
Dependencies: Common, Scheduling, Orchard.jQuery

View File

@@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
<!-- iis6 - for any request in this location, return via managed static file handler -->

View File

@@ -7,8 +7,18 @@ html.dyn input.hinted {
font-style:italic;
}
input#ArchiveLater_ScheduledArchiveDate {
width:50%;
width:49%;
}
input#ArchiveLater_ScheduledArchiveTime {
width:36%;
width:43%;
}
.edit-item-sidebar fieldset.archive-later-datetime {
float:left;
padding:0 0 8px 0;
}
fieldset.archive-later-datetime input {
padding:1px;
text-align:center;
color:#666;
}

View File

@@ -8,7 +8,7 @@
Script.Require("jQueryUtils_TimePicker");
}
<fieldset>
<fieldset class="archive-later-datetime">
<legend>@T("Archive Settings")</legend>
<div>
@Html.CheckBox("ArchiveLater", Model.ScheduledArchiveUtc.HasValue, new { id = ViewData.TemplateInfo.GetFullHtmlFieldId("Command_ArchiveLater") })

View File

@@ -1,6 +1,10 @@
<?xml version="1.0"?>
<configuration>
<system.web>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
</httpHandlers>

View File

@@ -1,7 +1,5 @@
using System.Linq;
using Orchard.Blogs.Services;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Aspects;
using Orchard.Localization;
using Orchard.UI.Navigation;
@@ -32,12 +30,12 @@ namespace Orchard.Blogs {
}
else if (singleBlog != null)
menu.Add(T("Manage Blog"), "1.0",
item => item.Action("Item", "BlogAdmin", new { area = "Orchard.Blogs", blogSlug = singleBlog.As<IRoutableAspect>().Path }).Permission(Permissions.MetaListBlogs));
item => item.Action("Item", "BlogAdmin", new { area = "Orchard.Blogs", blogId = singleBlog.Id }).Permission(Permissions.MetaListBlogs));
if (singleBlog != null)
menu.Add(T("Create New Post"), "1.1",
item =>
item.Action("Create", "BlogPostAdmin", new { area = "Orchard.Blogs", blogSlug = singleBlog.As<IRoutableAspect>().Path }).Permission(Permissions.PublishBlogPost));
item.Action("Create", "BlogPostAdmin", new { area = "Orchard.Blogs", blogId = singleBlog.Id }).Permission(Permissions.PublishBlogPost));
menu.Add(T("Create New Blog"), "1.2",
item =>

View File

@@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
<!-- iis6 - for any request in this location, return via managed static file handler -->

View File

@@ -1,5 +1,4 @@
using System.Linq;
using System.Reflection;
using System.Web.Mvc;
using Orchard.Blogs.Extensions;
using Orchard.Blogs.Models;
@@ -50,7 +49,7 @@ namespace Orchard.Blogs.Controllers {
if (!Services.Authorizer.Authorize(Permissions.ManageBlogs, T("Not allowed to create blogs")))
return new HttpUnauthorizedResult();
BlogPart blog = Services.ContentManager.New<BlogPart>("Blog");
var blog = Services.ContentManager.New<BlogPart>("Blog");
if (blog == null)
return HttpNotFound();
@@ -81,11 +80,11 @@ namespace Orchard.Blogs.Controllers {
return Redirect(Url.BlogForAdmin(blog));
}
public ActionResult Edit(int id) {
public ActionResult Edit(int blogId) {
if (!Services.Authorizer.Authorize(Permissions.ManageBlogs, T("Not allowed to edit blog")))
return new HttpUnauthorizedResult();
var blog = _blogService.Get(id, VersionOptions.Latest);
var blog = _blogService.Get(blogId, VersionOptions.Latest);
if (blog == null)
return HttpNotFound();
@@ -95,11 +94,11 @@ namespace Orchard.Blogs.Controllers {
}
[HttpPost, ActionName("Edit")]
public ActionResult EditPOST(int id) {
public ActionResult EditPOST(int blogId) {
if (!Services.Authorizer.Authorize(Permissions.ManageBlogs, T("Couldn't edit blog")))
return new HttpUnauthorizedResult();
var blog = _blogService.Get(id, VersionOptions.DraftRequired);
var blog = _blogService.Get(blogId, VersionOptions.DraftRequired);
if (blog == null)
return HttpNotFound();
@@ -118,11 +117,11 @@ namespace Orchard.Blogs.Controllers {
}
[HttpPost]
public ActionResult Remove(int id) {
public ActionResult Remove(int blogId) {
if (!Services.Authorizer.Authorize(Permissions.ManageBlogs, T("Couldn't delete blog")))
return new HttpUnauthorizedResult();
var blog = _blogService.Get(id, VersionOptions.Latest);
var blog = _blogService.Get(blogId, VersionOptions.Latest);
if (blog == null)
return HttpNotFound();
@@ -148,8 +147,8 @@ namespace Orchard.Blogs.Controllers {
return View((object)viewModel);
}
public ActionResult Item(string blogSlug, Pager pager) {
BlogPart blogPart = _blogService.Get(blogSlug);
public ActionResult Item(int blogId, Pager pager) {
BlogPart blogPart = _blogService.Get(blogId, VersionOptions.Latest).As<BlogPart>();
if (blogPart == null)
return HttpNotFound();

View File

@@ -1,11 +1,14 @@
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using Orchard.Blogs.Extensions;
using Orchard.Blogs.Routing;
using Orchard.Blogs.Services;
using Orchard.Core.Feeds;
using Orchard.Core.Routable.Services;
using Orchard.DisplayManagement;
using Orchard.Logging;
using Orchard.Services;
using Orchard.Themes;
using Orchard.UI.Navigation;
@@ -17,6 +20,8 @@ namespace Orchard.Blogs.Controllers {
private readonly IBlogPostService _blogPostService;
private readonly IBlogSlugConstraint _blogSlugConstraint;
private readonly IFeedManager _feedManager;
private readonly IWorkContextAccessor _workContextAccessor;
private readonly IHomePageProvider _routableHomePageProvider;
public BlogController(
IOrchardServices services,
@@ -24,12 +29,16 @@ namespace Orchard.Blogs.Controllers {
IBlogPostService blogPostService,
IBlogSlugConstraint blogSlugConstraint,
IFeedManager feedManager,
IShapeFactory shapeFactory) {
IShapeFactory shapeFactory,
IWorkContextAccessor workContextAccessor,
IEnumerable<IHomePageProvider> homePageProviders) {
_services = services;
_blogService = blogService;
_blogPostService = blogPostService;
_blogSlugConstraint = blogSlugConstraint;
_feedManager = feedManager;
_workContextAccessor = workContextAccessor;
_routableHomePageProvider = homePageProviders.SingleOrDefault(p => p.GetProviderName() == RoutableHomePageProvider.Name);
Logger = NullLogger.Instance;
Shape = shapeFactory;
}
@@ -59,6 +68,12 @@ namespace Orchard.Blogs.Controllers {
if (blogPart == null)
return HttpNotFound();
// primary action run for a home paged item shall not pass
if (!RouteData.DataTokens.ContainsKey("ParentActionViewContext")
&& blogPart.Id == _routableHomePageProvider.GetHomePageId(_workContextAccessor.GetContext().CurrentSite.HomePage)) {
return HttpNotFound();
}
_feedManager.Register(blogPart);
var blogPosts = _blogPostService.Get(blogPart, pager.GetStartIndex(), pager.PageSize)
.Select(b => _services.ContentManager.BuildDisplay(b, "Summary"));

View File

@@ -80,11 +80,11 @@ namespace Orchard.Blogs.Controllers {
//todo: the content shape template has extra bits that the core contents module does not (remove draft functionality)
//todo: - move this extra functionality there or somewhere else that's appropriate?
public ActionResult Edit(string blogSlug, int postId) {
public ActionResult Edit(int blogId, int postId) {
if (!Services.Authorizer.Authorize(Permissions.EditBlogPost, T("Couldn't edit blog post")))
return new HttpUnauthorizedResult();
var blog = _blogService.Get(blogSlug);
var blog = _blogService.Get(blogId, VersionOptions.Latest);
if (blog == null)
return HttpNotFound();
@@ -99,8 +99,8 @@ namespace Orchard.Blogs.Controllers {
[HttpPost, ActionName("Edit")]
[FormValueRequired("submit.Save")]
public ActionResult EditPOST(string blogSlug, int postId, string returnUrl) {
return EditPOST(blogSlug, postId, returnUrl, contentItem => {
public ActionResult EditPOST(int blogId, int postId, string returnUrl) {
return EditPOST(blogId, postId, returnUrl, contentItem => {
if (!contentItem.Has<IPublishingControlAspect>() && !contentItem.TypeDefinition.Settings.GetModel<ContentTypeSettings>().Draftable)
Services.ContentManager.Publish(contentItem);
});
@@ -108,15 +108,15 @@ namespace Orchard.Blogs.Controllers {
[HttpPost, ActionName("Edit")]
[FormValueRequired("submit.Publish")]
public ActionResult EditAndPublishPOST(string blogSlug, int postId, string returnUrl) {
return EditPOST(blogSlug, postId, returnUrl, contentItem => Services.ContentManager.Publish(contentItem));
public ActionResult EditAndPublishPOST(int blogId, int postId, string returnUrl) {
return EditPOST(blogId, postId, returnUrl, contentItem => Services.ContentManager.Publish(contentItem));
}
public ActionResult EditPOST(string blogSlug, int postId, string returnUrl, Action<ContentItem> conditionallyPublish) {
public ActionResult EditPOST(int blogId, int postId, string returnUrl, Action<ContentItem> conditionallyPublish) {
if (!Services.Authorizer.Authorize(Permissions.EditBlogPost, T("Couldn't edit blog post")))
return new HttpUnauthorizedResult();
var blog = _blogService.Get(blogSlug);
var blog = _blogService.Get(blogId, VersionOptions.Latest);
if (blog == null)
return HttpNotFound();
@@ -178,16 +178,16 @@ namespace Orchard.Blogs.Controllers {
ActionResult RedirectToEdit(IContent item) {
if (item == null || item.As<BlogPostPart>() == null)
return HttpNotFound();
return RedirectToAction("Edit", new { BlogSlug = item.As<IRoutableAspect>().Path, PostId = item.ContentItem.Id });
return RedirectToAction("Edit", new { BlogId = item.As<BlogPostPart>().BlogPart.Id, PostId = item.ContentItem.Id });
}
[ValidateAntiForgeryTokenOrchard]
public ActionResult Delete(string blogSlug, int postId) {
public ActionResult Delete(int blogId, int postId) {
//refactoring: test PublishBlogPost/PublishOthersBlogPost in addition if published
if (!Services.Authorizer.Authorize(Permissions.DeleteBlogPost, T("Couldn't delete blog post")))
return new HttpUnauthorizedResult();
var blog = _blogService.Get(blogSlug);
var blog = _blogService.Get(blogId, VersionOptions.Latest);
if (blog == null)
return HttpNotFound();
@@ -198,15 +198,15 @@ namespace Orchard.Blogs.Controllers {
_blogPostService.Delete(post);
Services.Notifier.Information(T("Blog post was successfully deleted"));
return Redirect(Url.BlogForAdmin(blog));
return Redirect(Url.BlogForAdmin(blog.As<BlogPart>()));
}
[ValidateAntiForgeryTokenOrchard]
public ActionResult Publish(string blogSlug, int postId) {
public ActionResult Publish(int blogId, int postId) {
if (!Services.Authorizer.Authorize(Permissions.PublishBlogPost, T("Couldn't publish blog post")))
return new HttpUnauthorizedResult();
var blog = _blogService.Get(blogSlug);
var blog = _blogService.Get(blogId, VersionOptions.Latest);
if (blog == null)
return HttpNotFound();
@@ -217,15 +217,15 @@ namespace Orchard.Blogs.Controllers {
_blogPostService.Publish(post);
Services.Notifier.Information(T("Blog post successfully published."));
return Redirect(Url.BlogForAdmin(blog));
return Redirect(Url.BlogForAdmin(blog.As<BlogPart>()));
}
[ValidateAntiForgeryTokenOrchard]
public ActionResult Unpublish(string blogSlug, int postId) {
public ActionResult Unpublish(int blogId, int postId) {
if (!Services.Authorizer.Authorize(Permissions.PublishBlogPost, T("Couldn't unpublish blog post")))
return new HttpUnauthorizedResult();
var blog = _blogService.Get(blogSlug);
var blog = _blogService.Get(blogId, VersionOptions.Latest);
if (blog == null)
return HttpNotFound();
@@ -236,7 +236,7 @@ namespace Orchard.Blogs.Controllers {
_blogPostService.Unpublish(post);
Services.Notifier.Information(T("Blog post successfully unpublished."));
return Redirect(Url.BlogForAdmin(blog));
return Redirect(Url.BlogForAdmin(blog.As<BlogPart>()));
}
bool IUpdateModel.TryUpdateModel<TModel>(TModel model, string prefix, string[] includeProperties, string[] excludeProperties) {

View File

@@ -40,23 +40,23 @@ namespace Orchard.Blogs.Extensions {
}
public static string BlogForAdmin(this UrlHelper urlHelper, BlogPart blogPart) {
return urlHelper.Action("Item", "BlogAdmin", new { blogSlug = blogPart.As<IRoutableAspect>().Path, area = "Orchard.Blogs" });
return urlHelper.Action("Item", "BlogAdmin", new { blogId = blogPart.Id, area = "Orchard.Blogs" });
}
public static string BlogCreate(this UrlHelper urlHelper) {
return urlHelper.Action("Create", "BlogAdmin", new {area = "Orchard.Blogs"});
return urlHelper.Action("Create", "BlogAdmin", new { area = "Orchard.Blogs" });
}
public static string BlogEdit(this UrlHelper urlHelper, BlogPart blogPart) {
return urlHelper.Action("Edit", "BlogAdmin", new { blogPart.Id, area = "Orchard.Blogs" });
return urlHelper.Action("Edit", "BlogAdmin", new { blogId = blogPart.Id, area = "Orchard.Blogs" });
}
public static string BlogRemove(this UrlHelper urlHelper, BlogPart blogPart) {
return urlHelper.Action("Remove", "BlogAdmin", new { blogPart.Id, area = "Orchard.Blogs" });
return urlHelper.Action("Remove", "BlogAdmin", new { blogId = blogPart.Id, area = "Orchard.Blogs" });
}
public static string BlogPostCreate(this UrlHelper urlHelper, BlogPart blogPart) {
return urlHelper.Action("Create", "BlogPostAdmin", new { blogSlug = blogPart.As<IRoutableAspect>().Path, area = "Orchard.Blogs" });
return urlHelper.Action("Create", "BlogPostAdmin", new { blogId = blogPart.Id, area = "Orchard.Blogs" });
}
public static string BlogPost(this UrlHelper urlHelper, BlogPostPart blogPostPart) {
@@ -64,19 +64,19 @@ namespace Orchard.Blogs.Extensions {
}
public static string BlogPostEdit(this UrlHelper urlHelper, BlogPostPart blogPostPart) {
return urlHelper.Action("Edit", "BlogPostAdmin", new { blogSlug = blogPostPart.BlogPart.As<IRoutableAspect>().Path, postId = blogPostPart.Id, area = "Orchard.Blogs" });
return urlHelper.Action("Edit", "BlogPostAdmin", new { blogId = blogPostPart.BlogPart.Id, postId = blogPostPart.Id, area = "Orchard.Blogs" });
}
public static string BlogPostDelete(this UrlHelper urlHelper, BlogPostPart blogPostPart) {
return urlHelper.Action("Delete", "BlogPostAdmin", new { blogSlug = blogPostPart.BlogPart.As<IRoutableAspect>().Path, postId = blogPostPart.Id, area = "Orchard.Blogs" });
return urlHelper.Action("Delete", "BlogPostAdmin", new { blogId = blogPostPart.BlogPart.Id, postId = blogPostPart.Id, area = "Orchard.Blogs" });
}
public static string BlogPostPublish(this UrlHelper urlHelper, BlogPostPart blogPostPart) {
return urlHelper.Action("Publish", "BlogPostAdmin", new { blogSlug = blogPostPart.BlogPart.As<IRoutableAspect>().Path, postId = blogPostPart.Id, area = "Orchard.Blogs" });
return urlHelper.Action("Publish", "BlogPostAdmin", new { blogId = blogPostPart.BlogPart.Id, postId = blogPostPart.Id, area = "Orchard.Blogs" });
}
public static string BlogPostUnpublish(this UrlHelper urlHelper, BlogPostPart blogPostPart) {
return urlHelper.Action("Unpublish", "BlogPostAdmin", new { blogSlug = blogPostPart.BlogPart.As<IRoutableAspect>().Path, postId = blogPostPart.Id, area = "Orchard.Blogs" });
return urlHelper.Action("Unpublish", "BlogPostAdmin", new { blogId = blogPostPart.BlogPart.Id, postId = blogPostPart.Id, area = "Orchard.Blogs" });
}
}
}

View File

@@ -14,6 +14,7 @@ namespace Orchard.Blogs.Handlers {
public class BlogPartArchiveHandler : ContentHandler {
public BlogPartArchiveHandler(IRepository<BlogPartArchiveRecord> blogArchiveRepository, IBlogPostService blogPostService) {
OnPublished<BlogPostPart>((context, bp) => RecalculateBlogArchive(blogArchiveRepository, blogPostService, bp));
OnUnpublished<BlogPostPart>((context, bp) => RecalculateBlogArchive(blogArchiveRepository, blogPostService, bp));
OnRemoved<BlogPostPart>((context, bp) => RecalculateBlogArchive(blogArchiveRepository, blogPostService, bp));
}

View File

@@ -1,21 +1,47 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Routing;
using JetBrains.Annotations;
using Orchard.Blogs.Models;
using Orchard.Blogs.Routing;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Handlers;
using Orchard.Core.Routable.Models;
using Orchard.Core.Routable.Services;
using Orchard.Data;
using Orchard.Services;
namespace Orchard.Blogs.Handlers {
[UsedImplicitly]
public class BlogPartHandler : ContentHandler {
public BlogPartHandler(IRepository<BlogPartRecord> repository) {
private readonly IWorkContextAccessor _workContextAccessor;
private readonly IBlogSlugConstraint _blogSlugConstraint;
private readonly IHomePageProvider _routableHomePageProvider;
public BlogPartHandler(IRepository<BlogPartRecord> repository, IWorkContextAccessor workContextAccessor, IEnumerable<IHomePageProvider> homePageProviders, IBlogSlugConstraint blogSlugConstraint) {
_workContextAccessor = workContextAccessor;
_blogSlugConstraint = blogSlugConstraint;
_routableHomePageProvider = homePageProviders.SingleOrDefault(p => p.GetProviderName() == RoutableHomePageProvider.Name);
Filters.Add(StorageFilter.For(repository));
Action<PublishContentContext, RoutePart> publishedHandler = (context, route) => {
if (route.Is<BlogPart>()) {
if (route.ContentItem.Id != 0 && route.PromoteToHomePage)
_blogSlugConstraint.AddSlug("");
}
else if (route.ContentItem.Id != 0 && route.PromoteToHomePage) {
_blogSlugConstraint.RemoveSlug("");
}
};
OnPublished<RoutePart>(publishedHandler);
OnUnpublished<RoutePart>(publishedHandler);
OnGetDisplayShape<BlogPart>((context, blog) => {
context.Shape.Description = blog.Description;
context.Shape.PostCount = blog.PostCount;
});
context.Shape.Description = blog.Description;
context.Shape.PostCount = blog.PostCount;
});
}
protected override void GetItemMetadata(GetContentItemMetadataContext context) {
@@ -24,11 +50,15 @@ namespace Orchard.Blogs.Handlers {
if (blog == null)
return;
var blogSlug = blog.Id == _routableHomePageProvider.GetHomePageId(_workContextAccessor.GetContext().CurrentSite.HomePage)
? ""
: blog.As<RoutePart>().Slug;
context.Metadata.DisplayRouteValues = new RouteValueDictionary {
{"Area", "Orchard.Blogs"},
{"Controller", "Blog"},
{"Action", "Item"},
{"blogSlug", blog.As<RoutePart>().Slug}
{"blogSlug", blogSlug}
};
context.Metadata.CreateRouteValues = new RouteValueDictionary {
{"Area", "Orchard.Blogs"},
@@ -39,13 +69,13 @@ namespace Orchard.Blogs.Handlers {
{"Area", "Orchard.Blogs"},
{"Controller", "BlogAdmin"},
{"Action", "Edit"},
{"Id", context.ContentItem.Id}
{"blogId", context.ContentItem.Id}
};
context.Metadata.RemoveRouteValues = new RouteValueDictionary {
{"Area", "Orchard.Blogs"},
{"Controller", "BlogAdmin"},
{"Action", "Remove"},
{"Id", context.ContentItem.Id}
{"blogId", context.ContentItem.Id}
};
}
}

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