diff --git a/AzurePackage.proj b/AzurePackage.proj
index 202ec1827..a5bc7ccfa 100644
--- a/AzurePackage.proj
+++ b/AzurePackage.proj
@@ -3,19 +3,19 @@
-
- $(MSBuildProjectDirectory)\lib
- $(MSBuildProjectDirectory)\src
- $(MSBuildProjectDirectory)\build
- $(MSBuildProjectDirectory)\artifacts\Azure
-
- $(BuildFolder)\Compile
- $(CompileFolder)\Orchard.Azure.CloudService.csx
- $(ServiceFolder)\roles\Orchard.Azure.Web\approot
- $(CompileFolder)\_PublishedWebsites
- $(BuildFolder)\Stage
-
-
+
+ $(MSBuildProjectDirectory)\lib
+ $(MSBuildProjectDirectory)\src
+ $(MSBuildProjectDirectory)\build
+ $(MSBuildProjectDirectory)\buildtasks
+ $(MSBuildProjectDirectory)\artifacts\Azure
+
+ $(BuildFolder)\Compile
+ $(CompileFolder)\Orchard.Azure.CloudService.csx
+ $(ServiceFolder)\roles\Orchard.Azure.Web\approot
+ $(CompileFolder)\_PublishedWebsites
+ $(BuildFolder)\Stage
+
@@ -39,10 +39,10 @@
-
-
-
-
+
+
+
+
-
-
-
-
-
+
+
+
+
-
+
+
+
@@ -112,6 +113,24 @@
XPath="/log4net/root/priority/@value"
Value="ERROR" />
+
+
+
+
+
+
+
+
+
+
+
+
-
+
diff --git a/Orchard.proj b/Orchard.proj
index 0d10ebf37..8a85e521a 100644
--- a/Orchard.proj
+++ b/Orchard.proj
@@ -231,6 +231,24 @@
XPath="/log4net/root/priority/@value"
Value="ERROR" />
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Orchard.Azure/AzureFileSystem.cs b/src/Orchard.Azure/AzureFileSystem.cs
index 05a42e61e..519a7477c 100644
--- a/src/Orchard.Azure/AzureFileSystem.cs
+++ b/src/Orchard.Azure/AzureFileSystem.cs
@@ -29,7 +29,7 @@ namespace Orchard.Azure {
_storageAccount = storageAccount;
ContainerName = containerName;
_root = String.IsNullOrEmpty(root) ? "": root + "/";
- _absoluteRoot = _storageAccount.BlobEndpoint.AbsoluteUri + "/" + containerName + "/" + root;
+ _absoluteRoot = Combine(Combine(_storageAccount.BlobEndpoint.AbsoluteUri, containerName), root);
using ( new HttpContextWeaver() ) {
diff --git a/src/Orchard.Azure/Orchard.Azure.Web/Default.aspx b/src/Orchard.Azure/Orchard.Azure.Web/Default.aspx
deleted file mode 100644
index fcae21248..000000000
--- a/src/Orchard.Azure/Orchard.Azure.Web/Default.aspx
+++ /dev/null
@@ -1,3 +0,0 @@
-<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Orchard.Azure.Web._Default" %>
-
-<%-- Please do not delete this file. It is used to ensure that ASP.NET MVC is activated by IIS when a user makes a "/" request to the server. --%>
diff --git a/src/Orchard.Azure/Orchard.Azure.Web/Default.aspx.cs b/src/Orchard.Azure/Orchard.Azure.Web/Default.aspx.cs
deleted file mode 100644
index 924ecd969..000000000
--- a/src/Orchard.Azure/Orchard.Azure.Web/Default.aspx.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using System;
-using System.Web;
-using System.Web.Mvc;
-using System.Web.UI;
-
-namespace Orchard.Azure.Web {
- public class _Default : Page {
- public void Page_Load(object sender, EventArgs e) {
- // Change the current path so that the Routing handler can correctly interpret
- // the request, then restore the original path so that the OutputCache module
- // can correctly process the response (if caching is enabled).
-
- var originalPath = Request.Path;
- HttpContext.Current.RewritePath(Request.ApplicationPath, false);
- IHttpHandler httpHandler = new MvcHttpHandler();
- httpHandler.ProcessRequest(HttpContext.Current);
- HttpContext.Current.RewritePath(originalPath, false);
- }
- }
-}
\ No newline at end of file
diff --git a/src/Orchard.Azure/Orchard.Azure.Web/Orchard.Azure.Web.csproj b/src/Orchard.Azure/Orchard.Azure.Web/Orchard.Azure.Web.csproj
index dd2703ca9..31d043fba 100644
--- a/src/Orchard.Azure/Orchard.Azure.Web/Orchard.Azure.Web.csproj
+++ b/src/Orchard.Azure/Orchard.Azure.Web/Orchard.Azure.Web.csproj
@@ -140,10 +140,6 @@
-
- Default.aspx
- ASPXCodeBehind
-
Global.asax
@@ -151,7 +147,6 @@
-
diff --git a/src/Orchard.Azure/Orchard.Azure.Web/Web.config b/src/Orchard.Azure/Orchard.Azure.Web/Web.config
index 92583c3f9..7c86d8a39 100644
--- a/src/Orchard.Azure/Orchard.Azure.Web/Web.config
+++ b/src/Orchard.Azure/Orchard.Azure.Web/Web.config
@@ -53,7 +53,7 @@
affects performance, set this value to true only
during development.
-->
-
+
@@ -116,7 +116,6 @@
-
@@ -133,7 +132,6 @@
-
@@ -142,7 +140,8 @@
-
+
+
diff --git a/src/Orchard.Tests.Modules/Indexing/LuceneIndexProviderTests.cs b/src/Orchard.Tests.Modules/Indexing/LuceneIndexProviderTests.cs
new file mode 100644
index 000000000..41a43c632
--- /dev/null
+++ b/src/Orchard.Tests.Modules/Indexing/LuceneIndexProviderTests.cs
@@ -0,0 +1,296 @@
+using System;
+using System.IO;
+using System.Linq;
+using Autofac;
+using Lucene.Services;
+using NUnit.Framework;
+using Orchard.Environment.Configuration;
+using Orchard.FileSystems.AppData;
+using Orchard.Indexing;
+using Orchard.Indexing.Services;
+using Orchard.Tests.FileSystems.AppData;
+
+namespace Orchard.Tests.Modules.Indexing {
+ public class LuceneIndexProviderTests {
+ private IContainer _container;
+ private IIndexProvider _provider;
+ private IAppDataFolder _appDataFolder;
+ private ShellSettings _shellSettings;
+ private readonly string _basePath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
+
+ [TestFixtureTearDown]
+ public void Clean() {
+ if (Directory.Exists(_basePath)) {
+ Directory.Delete(_basePath, true);
+ }
+ }
+
+ [SetUp]
+ public void Setup() {
+ if (Directory.Exists(_basePath)) {
+ Directory.Delete(_basePath, true);
+ }
+ Directory.CreateDirectory(_basePath);
+
+ _appDataFolder = AppDataFolderTests.CreateAppDataFolder(_basePath);
+
+ var builder = new ContainerBuilder();
+ builder.RegisterType().As();
+ builder.RegisterInstance(_appDataFolder).As();
+
+ // setting up a ShellSettings instance
+ _shellSettings = new ShellSettings { Name = "My Site" };
+ builder.RegisterInstance(_shellSettings).As();
+
+ _container = builder.Build();
+ _provider = _container.Resolve();
+ }
+
+ private string[] Indexes() {
+ return new DirectoryInfo(Path.Combine(_basePath, "Sites", "My Site", "Indexes")).GetDirectories().Select(d => d.Name).ToArray();
+ }
+
+ [Test]
+ public void IndexProviderShouldCreateNewIndex() {
+ Assert.That(Indexes().Length, Is.EqualTo(0));
+
+ _provider.CreateIndex("default");
+ Assert.That(Indexes().Length, Is.EqualTo(1));
+ }
+
+ [Test]
+ public void IndexProviderShouldOverwriteAlreadyExistingIndex() {
+ _provider.CreateIndex("default");
+ _provider.Store("default", _provider.New(1).Add("body", null));
+ Assert.That(_provider.IsEmpty("default"), Is.False);
+
+ _provider.CreateIndex("default");
+ Assert.That(_provider.IsEmpty("default"), Is.True);
+ }
+
+ [Test]
+ public void IndexProviderShouldDeleteExistingIndex() {
+ Assert.That(Indexes().Length, Is.EqualTo(0));
+
+ _provider.CreateIndex("default");
+ Assert.That(Indexes().Length, Is.EqualTo(1));
+
+ _provider.DeleteIndex("default");
+ Assert.That(Indexes().Length, Is.EqualTo(0));
+ }
+
+ [Test]
+ public void IndexProviderShouldListExistingIndexes() {
+ Assert.That(Indexes().Length, Is.EqualTo(0));
+
+ _provider.CreateIndex("default");
+ Assert.That(Indexes().Length, Is.EqualTo(1));
+ Assert.That(Indexes()[0], Is.EqualTo("default"));
+
+ _provider.CreateIndex("foo");
+ Assert.That(Indexes().Length, Is.EqualTo(2));
+ }
+
+ [Test]
+ public void ANewIndexShouldBeEmpty() {
+ _provider.CreateIndex("default");
+ var searchBuilder = _provider.CreateSearchBuilder("default");
+ var hits = searchBuilder.Search();
+
+ Assert.That(hits.Count(), Is.EqualTo(0));
+ }
+
+ [Test]
+ public void DocumentsShouldBeSearchableById() {
+ _provider.CreateIndex("default");
+
+ _provider.Store("default", _provider.New(42));
+
+ var searchBuilder = _provider.CreateSearchBuilder("default");
+
+ var hit = searchBuilder.Get(42);
+ Assert.IsNotNull(hit);
+ Assert.That(hit.ContentItemId, Is.EqualTo(42));
+
+ hit = searchBuilder.Get(1);
+ Assert.IsNull(hit);
+ }
+
+ [Test]
+ public void PropertiesShouldNotBeLost() {
+ _provider.CreateIndex("default");
+ _provider.Store("default", _provider.New(42).Add("prop1", "value1").Store());
+
+ var hit = _provider.CreateSearchBuilder("default").Get(42);
+
+ Assert.IsNotNull(hit);
+ Assert.That(hit.ContentItemId, Is.EqualTo(42));
+ Assert.That(hit.GetString("prop1"), Is.EqualTo("value1"));
+
+ }
+
+ [Test]
+ public void ShouldHandleMultipleIndexes() {
+ _provider.CreateIndex("default1");
+ _provider.Store("default1", _provider.New(1));
+
+ _provider.CreateIndex("default2");
+ _provider.Store("default2", _provider.New(2));
+
+ _provider.CreateIndex("default3");
+ _provider.Store("default3", _provider.New(3));
+
+ Assert.IsNotNull(_provider.CreateSearchBuilder("default1").Get(1));
+ Assert.IsNotNull(_provider.CreateSearchBuilder("default2").Get(2));
+ Assert.IsNotNull(_provider.CreateSearchBuilder("default3").Get(3));
+
+ Assert.IsNull(_provider.CreateSearchBuilder("default1").Get(2));
+ Assert.IsNull(_provider.CreateSearchBuilder("default2").Get(3));
+ Assert.IsNull(_provider.CreateSearchBuilder("default3").Get(1));
+
+ }
+
+ [Test]
+ public void IdentifierShouldNotCollide() {
+ _provider.CreateIndex("default");
+ _provider.Store("default", _provider.New(1).Add("field", "value1"));
+ _provider.Store("default", _provider.New(11).Add("field", "value11"));
+ _provider.Store("default", _provider.New(111).Add("field", "value111"));
+
+ var searchBuilder = _provider.CreateSearchBuilder("default");
+
+ Assert.That(searchBuilder.Get(1).ContentItemId, Is.EqualTo(1));
+ Assert.That(searchBuilder.Get(11).ContentItemId, Is.EqualTo(11));
+ Assert.That(searchBuilder.Get(111).ContentItemId, Is.EqualTo(111));
+ }
+
+ [Test]
+ public void TagsShouldBeRemoved() {
+ _provider.CreateIndex("default");
+ _provider.Store("default", _provider.New(1).Add("body", "
some content").Analyze());
+ _provider.Store("default", _provider.New(2).Add("body", "
some content").RemoveTags().Analyze());
+
+ var searchBuilder = _provider.CreateSearchBuilder("default");
+
+ Assert.That(searchBuilder.WithField("body", "hr").Search().Count(), Is.EqualTo(1));
+ Assert.That(searchBuilder.WithField("body", "hr").Search().First().ContentItemId, Is.EqualTo(1));
+ }
+
+ [Test] public void ShouldAllowNullOrEmptyStrings() {
+ _provider.CreateIndex("default");
+ _provider.Store("default", _provider.New(1).Add("body", null));
+ _provider.Store("default", _provider.New(2).Add("body", ""));
+ _provider.Store("default", _provider.New(3).Add("body", "
").RemoveTags());
+
+ var searchBuilder = _provider.CreateSearchBuilder("default");
+
+ Assert.That(searchBuilder.Get(1).ContentItemId, Is.EqualTo(1));
+ Assert.That(searchBuilder.Get(2).ContentItemId, Is.EqualTo(2));
+ Assert.That(searchBuilder.Get(3).ContentItemId, Is.EqualTo(3));
+ }
+
+ [Test]
+ public void ProviderShouldStoreSettings() {
+ _provider.CreateIndex("default");
+ Assert.That(_provider.GetLastIndexUtc("default"), Is.Null);
+
+ _provider.SetLastIndexUtc("default", new DateTime(2010, 1, 1, 1, 1, 1, 1));
+ Assert.That(_provider.GetLastIndexUtc("default"), Is.EqualTo(new DateTime(2010, 1, 1, 1, 1, 1, 0)));
+
+ _provider.SetLastIndexUtc("default", new DateTime(1901, 1, 1, 1, 1, 1, 1));
+ Assert.That(_provider.GetLastIndexUtc("default"), Is.EqualTo(LuceneIndexProvider.DefaultMinDateTime));
+ }
+
+ [Test]
+ public void IsEmptyShouldBeTrueForNoneExistingIndexes() {
+ _provider.IsEmpty("dummy");
+ Assert.That(_provider.IsEmpty("default"), Is.True);
+ }
+
+ [Test]
+ public void IsEmptyShouldBeTrueForJustNewIndexes() {
+ _provider.CreateIndex("default");
+ Assert.That(_provider.IsEmpty("default"), Is.True);
+ }
+
+ [Test]
+ public void IsEmptyShouldBeFalseWhenThereIsADocument() {
+ _provider.CreateIndex("default");
+ _provider.Store("default", _provider.New(1).Add("body", null));
+ Assert.That(_provider.IsEmpty("default"), Is.False);
+ }
+
+ [Test]
+ public void IsDirtyShouldBeFalseForNewDocuments() {
+ IDocumentIndex doc = _provider.New(1);
+ Assert.That(doc.IsDirty, Is.False);
+ }
+
+
+ [Test]
+ public void IsDirtyShouldBeTrueWhenIndexIsModified() {
+ IDocumentIndex doc;
+
+ doc = _provider.New(1);
+ doc.Add("foo", "value");
+ Assert.That(doc.IsDirty, Is.True);
+
+ doc = _provider.New(1);
+ doc.Add("foo", false);
+ Assert.That(doc.IsDirty, Is.True);
+
+ doc = _provider.New(1);
+ doc.Add("foo", (float)1.0);
+ Assert.That(doc.IsDirty, Is.True);
+
+ doc = _provider.New(1);
+ doc.Add("foo", 1);
+ Assert.That(doc.IsDirty, Is.True);
+
+ doc = _provider.New(1);
+ doc.Add("foo", DateTime.Now);
+ Assert.That(doc.IsDirty, Is.True);
+
+ }
+
+ [Test]
+ public void DocumentsShouldBeDeleted() {
+ _provider.CreateIndex("default");
+ _provider.Store("default", _provider.New(1).Add("field", "value1"));
+ _provider.Store("default", _provider.New(11).Add("field", "value11"));
+ _provider.Store("default", _provider.New(111).Add("field", "value111"));
+
+ var searchBuilder = _provider.CreateSearchBuilder("default");
+
+ Assert.That(searchBuilder.Get(1).ContentItemId, Is.EqualTo(1));
+ Assert.That(searchBuilder.Get(11).ContentItemId, Is.EqualTo(11));
+ Assert.That(searchBuilder.Get(111).ContentItemId, Is.EqualTo(111));
+
+ _provider.Delete("default", 1);
+
+ Assert.That(searchBuilder.Get(1), Is.Null);
+ Assert.That(searchBuilder.Get(11).ContentItemId, Is.EqualTo(11));
+ Assert.That(searchBuilder.Get(111).ContentItemId, Is.EqualTo(111));
+
+ _provider.Delete("default", new int[] {1, 11, 111 });
+
+ Assert.That(searchBuilder.Get(1), Is.Null);
+ Assert.That(searchBuilder.Get(11), Is.Null);
+ Assert.That(searchBuilder.Get(111), Is.Null);
+
+ }
+
+ [Test]
+ public void SameContentItemShouldNotBeIndexedTwice() {
+ _provider.CreateIndex("default");
+
+ var searchBuilder = _provider.CreateSearchBuilder("default");
+
+ _provider.Store("default", _provider.New(1).Add("field", "value1"));
+ Assert.That(searchBuilder.WithField("id", "1").Count(), Is.EqualTo(1));
+
+ _provider.Store("default", _provider.New(1).Add("field", "value2"));
+ Assert.That(searchBuilder.WithField("id", "1").Count(), Is.EqualTo(1));
+ }
+ }
+}
diff --git a/src/Orchard.Tests.Modules/Indexing/LuceneSearchBuilderTests.cs b/src/Orchard.Tests.Modules/Indexing/LuceneSearchBuilderTests.cs
new file mode 100644
index 000000000..1b1d19aee
--- /dev/null
+++ b/src/Orchard.Tests.Modules/Indexing/LuceneSearchBuilderTests.cs
@@ -0,0 +1,337 @@
+using System;
+using System.IO;
+using System.Linq;
+using Autofac;
+using Lucene.Services;
+using NUnit.Framework;
+using Orchard.Environment.Configuration;
+using Orchard.FileSystems.AppData;
+using Orchard.Indexing;
+using Orchard.Indexing.Services;
+using Orchard.Tests.FileSystems.AppData;
+
+namespace Orchard.Tests.Modules.Indexing {
+ public class LuceneSearchBuilderTests {
+ private IContainer _container;
+ private IIndexProvider _provider;
+ private IAppDataFolder _appDataFolder;
+ private ShellSettings _shellSettings;
+ private readonly string _basePath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
+
+ [TestFixtureTearDown]
+ public void Clean() {
+ if (Directory.Exists(_basePath)) {
+ Directory.Delete(_basePath, true);
+ }
+ }
+
+ [SetUp]
+ public void Setup() {
+ if (Directory.Exists(_basePath)) {
+ Directory.Delete(_basePath, true);
+ }
+ Directory.CreateDirectory(_basePath);
+
+ _appDataFolder = AppDataFolderTests.CreateAppDataFolder(_basePath);
+
+ var builder = new ContainerBuilder();
+ builder.RegisterType().As();
+ builder.RegisterInstance(_appDataFolder).As();
+
+ // setting up a ShellSettings instance
+ _shellSettings = new ShellSettings { Name = "My Site" };
+ builder.RegisterInstance(_shellSettings).As();
+
+ _container = builder.Build();
+ _provider = _container.Resolve();
+ }
+
+ private ISearchBuilder _searchBuilder { get { return _provider.CreateSearchBuilder("default"); } }
+
+ [Test]
+ public void SearchTermsShouldBeFoundInMultipleFields() {
+ _provider.CreateIndex("default");
+ _provider.Store("default",
+ _provider.New(42)
+ .Add("title", "title1 title2 title3").Analyze()
+ .Add("date", new DateTime(2010, 05, 28, 14, 13, 56, 123))
+ );
+
+ Assert.IsNotNull(_provider.CreateSearchBuilder("default").Get(42));
+
+ Assert.IsNotNull(_provider.CreateSearchBuilder("default").WithField("title", "title1").Search().FirstOrDefault());
+ Assert.IsNotNull(_provider.CreateSearchBuilder("default").WithField("title", "title2").Search().FirstOrDefault());
+ Assert.IsNotNull(_provider.CreateSearchBuilder("default").WithField("title", "title3").Search().FirstOrDefault());
+ Assert.IsNull(_provider.CreateSearchBuilder("default").WithField("title", "title4").Search().FirstOrDefault());
+
+ }
+
+ [Test]
+ public void ShouldSearchById() {
+ _provider.CreateIndex("default");
+ _provider.Store("default", _provider.New(1));
+ _provider.Store("default", _provider.New(2));
+ _provider.Store("default", _provider.New(3));
+
+
+ Assert.That(_searchBuilder.Get(1).ContentItemId, Is.EqualTo(1));
+ Assert.That(_searchBuilder.Get(2).ContentItemId, Is.EqualTo(2));
+ Assert.That(_searchBuilder.Get(3).ContentItemId, Is.EqualTo(3));
+ }
+
+ [Test]
+ public void ShouldSearchWithField() {
+ _provider.CreateIndex("default");
+ _provider.Store("default", _provider.New(1).Add("title", "cat"));
+ _provider.Store("default", _provider.New(2).Add("title", "dog"));
+ _provider.Store("default", _provider.New(3).Add("title", "cat"));
+
+
+ Assert.That(_searchBuilder.WithField("title", "cat").Search().Count(), Is.EqualTo(2));
+ Assert.That(_searchBuilder.WithField("title", "cat").Search().Any(hit => new[] { 1, 3 }.Contains(hit.ContentItemId)), Is.True);
+
+ }
+
+ [Test]
+ public void ShouldCountResultsOnly() {
+ _provider.CreateIndex("default");
+ _provider.Store("default", _provider.New(1).Add("title", "cat"));
+ _provider.Store("default", _provider.New(2).Add("title", "dog"));
+ _provider.Store("default", _provider.New(3).Add("title", "cat"));
+
+ Assert.That(_searchBuilder.WithField("title", "dog").Count(), Is.EqualTo(1));
+ Assert.That(_searchBuilder.WithField("title", "cat").Count(), Is.EqualTo(2));
+ }
+
+ [Test]
+ public void ShouldFilterByDate() {
+ _provider.CreateIndex("default");
+ _provider.Store("default", _provider.New(1).Add("date", new DateTime(2010, 05, 28, 12, 30, 15)));
+ _provider.Store("default", _provider.New(2).Add("date", new DateTime(2010, 05, 28, 12, 30, 30)));
+ _provider.Store("default", _provider.New(3).Add("date", new DateTime(2010, 05, 28, 12, 30, 45)));
+
+ Assert.That(_searchBuilder.WithinRange("date", new DateTime(2010, 05, 28, 12, 30, 15), DateTime.MaxValue).Count(), Is.EqualTo(3));
+ Assert.That(_searchBuilder.WithinRange("date", DateTime.MinValue, new DateTime(2010, 05, 28, 12, 30, 45)).Count(), Is.EqualTo(3));
+ Assert.That(_searchBuilder.WithinRange("date", new DateTime(2010, 05, 28, 12, 30, 15), new DateTime(2010, 05, 28, 12, 30, 45)).Count(), Is.EqualTo(3));
+ Assert.That(_searchBuilder.WithinRange("date", new DateTime(2010, 05, 28, 12, 30, 16), new DateTime(2010, 05, 28, 12, 30, 44)).Count(), Is.EqualTo(1));
+ Assert.That(_searchBuilder.WithinRange("date", new DateTime(2010, 05, 28, 12, 30, 46), DateTime.MaxValue).Count(), Is.EqualTo(0));
+ Assert.That(_searchBuilder.WithinRange("date", DateTime.MinValue, new DateTime(2010, 05, 28, 12, 30, 1)).Count(), Is.EqualTo(0));
+ }
+
+ [Test]
+ public void ShouldSliceResults() {
+ _provider.CreateIndex("default");
+ _provider.Store("default", _provider.New(1));
+ _provider.Store("default", _provider.New(22));
+ _provider.Store("default", _provider.New(333));
+ _provider.Store("default", _provider.New(4444));
+ _provider.Store("default", _provider.New(55555));
+
+
+ Assert.That(_searchBuilder.Count(), Is.EqualTo(5));
+ Assert.That(_searchBuilder.Slice(0, 3).Count(), Is.EqualTo(3));
+ Assert.That(_searchBuilder.Slice(1, 3).Count(), Is.EqualTo(3));
+ Assert.That(_searchBuilder.Slice(3, 3).Count(), Is.EqualTo(2));
+
+ // Count() and Search() should return the same results
+ Assert.That(_searchBuilder.Search().Count(), Is.EqualTo(5));
+ Assert.That(_searchBuilder.Slice(0, 3).Search().Count(), Is.EqualTo(3));
+ Assert.That(_searchBuilder.Slice(1, 3).Search().Count(), Is.EqualTo(3));
+ Assert.That(_searchBuilder.Slice(3, 3).Search().Count(), Is.EqualTo(2));
+ }
+
+ [Test]
+ public void ShouldSortByRelevance() {
+ _provider.CreateIndex("default");
+ _provider.Store("default", _provider.New(1).Add("body", "michael is in the kitchen").Analyze());
+ _provider.Store("default", _provider.New(2).Add("body", "michael as a cousin named michel").Analyze());
+ _provider.Store("default", _provider.New(3).Add("body", "speak inside the mic").Analyze());
+ _provider.Store("default", _provider.New(4).Add("body", "a dog is pursuing a cat").Analyze());
+ _provider.Store("default", _provider.New(5).Add("body", "the elephant can't catch up the dog").Analyze());
+
+ var michael = _searchBuilder.WithField("body", "michael").Search().ToList();
+ Assert.That(michael.Count(), Is.EqualTo(2));
+ Assert.That(michael[0].Score >= michael[1].Score, Is.True);
+
+ // Sorting on score is always descending
+ michael = _searchBuilder.WithField("body", "michael").Ascending().Search().ToList();
+ Assert.That(michael.Count(), Is.EqualTo(2));
+ Assert.That(michael[0].Score >= michael[1].Score, Is.True);
+ }
+
+ [Test]
+ public void ShouldSortByDate() {
+ _provider.CreateIndex("default");
+ _provider.Store("default", _provider.New(1).Add("date", new DateTime(2010, 05, 28, 12, 30, 15)).Store());
+ _provider.Store("default", _provider.New(2).Add("date", new DateTime(2010, 05, 28, 12, 30, 30)).Store());
+ _provider.Store("default", _provider.New(3).Add("date", new DateTime(2010, 05, 28, 12, 30, 45)).Store());
+
+ var date = _searchBuilder.SortBy("date").Search().ToList();
+ Assert.That(date.Count(), Is.EqualTo(3));
+ Assert.That(date[0].GetDateTime("date") > date[1].GetDateTime("date"), Is.True);
+ Assert.That(date[1].GetDateTime("date") > date[2].GetDateTime("date"), Is.True);
+
+ date = _searchBuilder.SortBy("date").Ascending().Search().ToList();
+ Assert.That(date.Count(), Is.EqualTo(3));
+ Assert.That(date[0].GetDateTime("date") < date[1].GetDateTime("date"), Is.True);
+ Assert.That(date[1].GetDateTime("date") < date[2].GetDateTime("date"), Is.True);
+ }
+
+ [Test]
+ public void ShouldEscapeSpecialChars() {
+ _provider.CreateIndex("default");
+ _provider.Store("default", _provider.New(1).Add("body", "Orchard has been developped in C#").Analyze());
+ _provider.Store("default", _provider.New(2).Add("body", "Windows has been developped in C++").Analyze());
+
+ var cs = _searchBuilder.Parse("body", "C#").Search().ToList();
+ Assert.That(cs.Count(), Is.EqualTo(2));
+
+ var cpp = _searchBuilder.Parse("body", "C++").Search().ToList();
+ Assert.That(cpp.Count(), Is.EqualTo(2));
+
+ }
+
+ [Test]
+ public void ShouldHandleMandatoryFields() {
+ _provider.CreateIndex("default");
+ _provider.Store("default", _provider.New(1).Add("body", "Orchard has been developped in C#").Analyze());
+ _provider.Store("default", _provider.New(2).Add("body", "Windows has been developped in C++").Analyze());
+
+ Assert.That(_searchBuilder.WithField("body", "develop").Search().ToList().Count(), Is.EqualTo(2));
+ Assert.That(_searchBuilder.WithField("body", "develop").WithField("body", "Orchard").Search().ToList().Count(), Is.EqualTo(2));
+ Assert.That(_searchBuilder.WithField("body", "develop").WithField("body", "Orchard").Mandatory().Search().ToList().Count(), Is.EqualTo(1));
+ Assert.That(_searchBuilder.WithField("body", "develop").WithField("body", "Orchard").Mandatory().Search().First().ContentItemId, Is.EqualTo(1));
+ }
+
+ [Test]
+ public void ShouldHandleForbiddenFields() {
+ _provider.CreateIndex("default");
+ _provider.Store("default", _provider.New(1).Add("body", "Orchard has been developped in C#").Analyze());
+ _provider.Store("default", _provider.New(2).Add("body", "Windows has been developped in C++").Analyze());
+
+ Assert.That(_searchBuilder.WithField("body", "developped").Search().ToList().Count(), Is.EqualTo(2));
+ Assert.That(_searchBuilder.WithField("body", "developped").WithField("body", "Orchard").Search().ToList().Count(), Is.EqualTo(2));
+ Assert.That(_searchBuilder.WithField("body", "developped").WithField("body", "Orchard").Forbidden().Search().ToList().Count(), Is.EqualTo(1));
+ Assert.That(_searchBuilder.WithField("body", "developped").WithField("body", "Orchard").Forbidden().Search().First().ContentItemId, Is.EqualTo(2));
+ }
+
+ [Test]
+ public void ShouldHandleWeight() {
+ _provider.CreateIndex("default");
+ _provider.Store("default", _provider.New(1).Add("body", "Orchard has been developped in C#").Analyze());
+ _provider.Store("default", _provider.New(2).Add("body", "Windows has been developped in C++").Analyze());
+
+ Assert.That(_searchBuilder.WithField("body", "developped").WithField("body", "Orchard").Weighted(2).Search().First().ContentItemId, Is.EqualTo(1));
+ }
+
+ [Test]
+ public void ShouldParseLuceneQueries() {
+ _provider.CreateIndex("default");
+ _provider.Store("default", _provider.New(1).Add("body", "Bradley is in the kitchen.").Analyze().Add("title", "Beer and takos").Analyze());
+ _provider.Store("default", _provider.New(2).Add("body", "Renaud is also in the kitchen.").Analyze().Add("title", "A love affair").Analyze());
+ _provider.Store("default", _provider.New(3).Add("body", "Bertrand is a little bit jealous.").Analyze().Add("title", "Soap opera").Analyze());
+
+ Assert.That(_searchBuilder.Parse(new[] { "body" }, "kitchen").Count(), Is.EqualTo(2));
+ Assert.That(_searchBuilder.Parse(new[] { "body" }, "kitchen bertrand").Count(), Is.EqualTo(3));
+ Assert.That(_searchBuilder.Parse(new[] { "body" }, "kitchen +bertrand").Count(), Is.EqualTo(1));
+ Assert.That(_searchBuilder.Parse(new[] { "body" }, "+kitchen +bertrand").Count(), Is.EqualTo(0));
+ Assert.That(_searchBuilder.Parse(new[] { "body" }, "kit").Count(), Is.EqualTo(0));
+ Assert.That(_searchBuilder.Parse(new[] { "body" }, "kit*").Count(), Is.EqualTo(2));
+ Assert.That(_searchBuilder.Parse(new[] { "body", "title" }, "bradley love^3 soap").Count(), Is.EqualTo(3));
+ Assert.That(_searchBuilder.Parse(new[] { "body", "title" }, "bradley love^3 soap").Search().First().ContentItemId, Is.EqualTo(2));
+ }
+
+ [Test]
+ public void ShouldFilterIntValues() {
+ _provider.CreateIndex("default");
+ _provider.Store("default", _provider.New(1).Add("field", 1));
+ _provider.Store("default", _provider.New(2).Add("field", 22));
+ _provider.Store("default", _provider.New(3).Add("field", 333));
+
+ Assert.That(_searchBuilder.WithField("field", 1).ExactMatch().Count(), Is.EqualTo(1));
+ Assert.That(_searchBuilder.WithField("field", 22).ExactMatch().Count(), Is.EqualTo(1));
+ Assert.That(_searchBuilder.WithField("field", 333).ExactMatch().Count(), Is.EqualTo(1));
+
+ Assert.That(_searchBuilder.WithField("field", 0).ExactMatch().Count(), Is.EqualTo(0));
+ Assert.That(_searchBuilder.WithField("field", 2).ExactMatch().Count(), Is.EqualTo(0));
+ Assert.That(_searchBuilder.WithField("field", 3).ExactMatch().Count(), Is.EqualTo(0));
+ }
+
+ [Test]
+ public void ShouldFilterStoredIntValues() {
+ _provider.CreateIndex("default");
+ _provider.Store("default", _provider.New(1).Add("field", 1).Store());
+ _provider.Store("default", _provider.New(2).Add("field", 22).Store());
+ _provider.Store("default", _provider.New(3).Add("field", 333).Store());
+
+ Assert.That(_searchBuilder.WithField("field", 1).ExactMatch().Count(), Is.EqualTo(1));
+ Assert.That(_searchBuilder.WithField("field", 22).ExactMatch().Count(), Is.EqualTo(1));
+ Assert.That(_searchBuilder.WithField("field", 333).ExactMatch().Count(), Is.EqualTo(1));
+
+ Assert.That(_searchBuilder.WithField("field", 0).ExactMatch().Count(), Is.EqualTo(0));
+ Assert.That(_searchBuilder.WithField("field", 2).ExactMatch().Count(), Is.EqualTo(0));
+ Assert.That(_searchBuilder.WithField("field", 3).ExactMatch().Count(), Is.EqualTo(0));
+ }
+
+ [Test]
+ public void ShouldProvideAvailableFields() {
+ _provider.CreateIndex("default");
+ _provider.Store("default", _provider.New(1).Add("a", "Home").Analyze());
+ _provider.Store("default", _provider.New(2).Add("b", DateTime.Now).Store());
+ _provider.Store("default", _provider.New(3).Add("c", 333));
+
+ Assert.That(_provider.GetFields("default").Count(), Is.EqualTo(4));
+ Assert.That(_provider.GetFields("default").OrderBy(s => s).ToArray(), Is.EqualTo(new [] { "a", "b", "c", "id"}));
+ }
+
+ [Test]
+ public void FiltersShouldNotAlterResults() {
+ _provider.CreateIndex("default");
+ _provider.Store("default", _provider.New(1).Add("body", "Orchard has been developped by Mirosoft in C#").Analyze().Add("culture", 1033));
+ _provider.Store("default", _provider.New(2).Add("body", "Windows a été développé par Mirosoft en C++").Analyze().Add("culture", 1036));
+ _provider.Store("default", _provider.New(3).Add("title", "Home").Analyze().Add("culture", 1033));
+
+ Assert.That(_searchBuilder.WithField("body", "Mirosoft").Count(), Is.EqualTo(2));
+ Assert.That(_searchBuilder.WithField("body", "Mirosoft").WithField("culture", 1033).Count(), Is.EqualTo(3));
+ Assert.That(_searchBuilder.WithField("body", "Mirosoft").WithField("culture", 1033).AsFilter().Count(), Is.EqualTo(1));
+
+ Assert.That(_searchBuilder.WithField("body", "Orchard").WithField("culture", 1036).Count(), Is.EqualTo(2));
+ Assert.That(_searchBuilder.WithField("body", "Orchard").WithField("culture", 1036).AsFilter().Count(), Is.EqualTo(0));
+
+ Assert.That(_searchBuilder.WithField("culture", 1033).Count(), Is.EqualTo(2));
+ Assert.That(_searchBuilder.WithField("culture", 1033).AsFilter().Count(), Is.EqualTo(2));
+
+ Assert.That(_searchBuilder.WithField("body", "blabla").WithField("culture", 1033).Count(), Is.EqualTo(2));
+ Assert.That(_searchBuilder.WithField("body", "blabla").WithField("culture", 1033).AsFilter().Count(), Is.EqualTo(0));
+
+ Assert.That(_searchBuilder.Parse("title", "home").Count(), Is.EqualTo(1));
+ Assert.That(_searchBuilder.Parse("title", "home").WithField("culture", 1033).AsFilter().Count(), Is.EqualTo(1));
+ }
+
+ [Test]
+ public void FieldsCanContainMultipleValue() {
+ _provider.CreateIndex("default");
+ var documentIndex = _provider.New(1)
+ .Add("tag-id", 1)
+ .Add("tag-id", 2)
+ .Add("tag-id", 3)
+ .Add("tag-value", "tag1")
+ .Add("tag-value", "tag2")
+ .Add("tag-value", "tag3");
+
+ _provider.Store("default", documentIndex);
+
+ Assert.That(_searchBuilder.WithField("tag-id", 0).Count(), Is.EqualTo(0));
+ Assert.That(_searchBuilder.WithField("tag-id", 1).Count(), Is.EqualTo(1));
+ Assert.That(_searchBuilder.WithField("tag-id", 2).Count(), Is.EqualTo(1));
+ Assert.That(_searchBuilder.WithField("tag-id", 3).Count(), Is.EqualTo(1));
+
+ Assert.That(_searchBuilder.WithField("tag-value", "tag").ExactMatch().Count(), Is.EqualTo(0));
+ Assert.That(_searchBuilder.WithField("tag-value", "tag1").ExactMatch().Count(), Is.EqualTo(1));
+ Assert.That(_searchBuilder.WithField("tag-value", "tag2").ExactMatch().Count(), Is.EqualTo(1));
+ Assert.That(_searchBuilder.WithField("tag-value", "tag3").ExactMatch().Count(), Is.EqualTo(1));
+
+ Assert.That(_searchBuilder.WithField("tag-value", "tag").Count(), Is.EqualTo(1));
+ }
+ }
+}
diff --git a/src/Orchard.Tests.Modules/Orchard.Tests.Modules.csproj b/src/Orchard.Tests.Modules/Orchard.Tests.Modules.csproj
index 02b5112a1..65360fa8e 100644
--- a/src/Orchard.Tests.Modules/Orchard.Tests.Modules.csproj
+++ b/src/Orchard.Tests.Modules/Orchard.Tests.Modules.csproj
@@ -136,6 +136,8 @@
+
+
@@ -176,6 +178,10 @@
{9916839C-39FC-4CEB-A5AF-89CA7E87119F}
Orchard.Core
+
+ {D5D447D7-EF8E-43A6-B9A4-3B025DD9F45D}
+ Lucene
+
{C0C45321-B51D-4D8D-9B7B-AA4C2E0B2962}
Orchard.CodeGeneration
@@ -184,6 +190,10 @@
{14C049FD-B35B-415A-A824-87F26B26E7FD}
Orchard.Comments
+
+ {EA2B9121-EF54-40A6-A53E-6593C86EE696}
+ Orchard.Indexing
+
{D9A7B330-CD22-4DA1-A95A-8DE1982AD8EB}
Orchard.Media
diff --git a/src/Orchard.Web/Config/log4net.config b/src/Orchard.Web/Config/log4net.config
index e25fa3c7f..3dc7e72bd 100644
--- a/src/Orchard.Web/Config/log4net.config
+++ b/src/Orchard.Web/Config/log4net.config
@@ -8,7 +8,7 @@
-
+
@@ -28,7 +28,6 @@
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
@@ -70,10 +54,29 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
diff --git a/src/Orchard.Web/Core/Containers/Controllers/ItemController.cs b/src/Orchard.Web/Core/Containers/Controllers/ItemController.cs
index 6bb1e3618..da09b9d91 100644
--- a/src/Orchard.Web/Core/Containers/Controllers/ItemController.cs
+++ b/src/Orchard.Web/Core/Containers/Controllers/ItemController.cs
@@ -9,9 +9,9 @@ using Orchard.Core.Routable.Models;
using Orchard.DisplayManagement;
using Orchard.Themes;
using Orchard.UI.Navigation;
+using Orchard.Settings;
namespace Orchard.Core.Containers.Controllers {
- using Orchard.Settings;
public class ItemController : Controller {
private readonly IContentManager _contentManager;
diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Controllers/BlogAdminController.cs b/src/Orchard.Web/Modules/Orchard.Blogs/Controllers/BlogAdminController.cs
index 3d8206ff1..4e3687d25 100644
--- a/src/Orchard.Web/Modules/Orchard.Blogs/Controllers/BlogAdminController.cs
+++ b/src/Orchard.Web/Modules/Orchard.Blogs/Controllers/BlogAdminController.cs
@@ -14,9 +14,9 @@ using Orchard.Localization;
using Orchard.UI.Admin;
using Orchard.UI.Navigation;
using Orchard.UI.Notify;
+using Orchard.Settings;
namespace Orchard.Blogs.Controllers {
- using Orchard.Settings;
[ValidateInput(false), Admin]
public class BlogAdminController : Controller, IUpdateModel {
diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Controllers/BlogController.cs b/src/Orchard.Web/Modules/Orchard.Blogs/Controllers/BlogController.cs
index 43a78d750..a200fa074 100644
--- a/src/Orchard.Web/Modules/Orchard.Blogs/Controllers/BlogController.cs
+++ b/src/Orchard.Web/Modules/Orchard.Blogs/Controllers/BlogController.cs
@@ -11,9 +11,9 @@ using Orchard.Logging;
using Orchard.Services;
using Orchard.Themes;
using Orchard.UI.Navigation;
+using Orchard.Settings;
namespace Orchard.Blogs.Controllers {
- using Orchard.Settings;
[Themed]
public class BlogController : Controller {
diff --git a/src/Orchard.Web/Modules/Orchard.Packaging/Service References/GalleryServer/Reference.cs b/src/Orchard.Web/Modules/Orchard.Packaging/Service References/GalleryServer/Reference.cs
index 6fb1ab90c..cd11a7266 100644
--- a/src/Orchard.Web/Modules/Orchard.Packaging/Service References/GalleryServer/Reference.cs
+++ b/src/Orchard.Web/Modules/Orchard.Packaging/Service References/GalleryServer/Reference.cs
@@ -9,7 +9,7 @@
//------------------------------------------------------------------------------
// Original file name:
-// Generation date: 12/8/2010 3:18:34 PM
+// Generation date: 12/13/2010 12:55:40 PM
namespace Orchard.Packaging.GalleryServer
{
@@ -127,7 +127,7 @@ namespace Orchard.Packaging.GalleryServer
/// Initial value of DownloadCount.
/// Initial value of PackageSize.
/// Initial value of Rating.
- /// Initial value of RatingCount.
+ /// Initial value of RatingsCount.
/// Initial value of Price.
/// Initial value of RequireLicenseAcceptance.
/// Initial value of IsLatestVersion.
@@ -135,7 +135,7 @@ namespace Orchard.Packaging.GalleryServer
/// Initial value of LastUpdated.
/// Initial value of Published.
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Services.Design", "1.0.0")]
- public static PublishedPackage CreatePublishedPackage(string ID, string version, int downloadCount, long packageSize, double rating, int ratingCount, decimal price, bool requireLicenseAcceptance, bool isLatestVersion, global::System.DateTime created, global::System.DateTime lastUpdated, global::System.DateTime published)
+ public static PublishedPackage CreatePublishedPackage(string ID, string version, int downloadCount, long packageSize, double rating, int ratingsCount, decimal price, bool requireLicenseAcceptance, bool isLatestVersion, global::System.DateTime created, global::System.DateTime lastUpdated, global::System.DateTime published)
{
PublishedPackage publishedPackage = new PublishedPackage();
publishedPackage.Id = ID;
@@ -143,7 +143,7 @@ namespace Orchard.Packaging.GalleryServer
publishedPackage.DownloadCount = downloadCount;
publishedPackage.PackageSize = packageSize;
publishedPackage.Rating = rating;
- publishedPackage.RatingCount = ratingCount;
+ publishedPackage.RatingsCount = ratingsCount;
publishedPackage.Price = price;
publishedPackage.RequireLicenseAcceptance = requireLicenseAcceptance;
publishedPackage.IsLatestVersion = isLatestVersion;
@@ -426,26 +426,26 @@ namespace Orchard.Packaging.GalleryServer
partial void OnRatingChanging(double value);
partial void OnRatingChanged();
///
- /// There are no comments for Property RatingCount in the schema.
+ /// There are no comments for Property RatingsCount in the schema.
///
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Services.Design", "1.0.0")]
- public int RatingCount
+ public int RatingsCount
{
get
{
- return this._RatingCount;
+ return this._RatingsCount;
}
set
{
- this.OnRatingCountChanging(value);
- this._RatingCount = value;
- this.OnRatingCountChanged();
+ this.OnRatingsCountChanging(value);
+ this._RatingsCount = value;
+ this.OnRatingsCountChanged();
}
}
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Services.Design", "1.0.0")]
- private int _RatingCount;
- partial void OnRatingCountChanging(int value);
- partial void OnRatingCountChanged();
+ private int _RatingsCount;
+ partial void OnRatingsCountChanging(int value);
+ partial void OnRatingsCountChanged();
///
/// There are no comments for Property Price in the schema.
///
diff --git a/src/Orchard.Web/Modules/Orchard.Packaging/Service References/GalleryServer/service.edmx b/src/Orchard.Web/Modules/Orchard.Packaging/Service References/GalleryServer/service.edmx
index 514d12de3..edd4b0cbb 100644
--- a/src/Orchard.Web/Modules/Orchard.Packaging/Service References/GalleryServer/service.edmx
+++ b/src/Orchard.Web/Modules/Orchard.Packaging/Service References/GalleryServer/service.edmx
@@ -19,7 +19,7 @@
-
+
diff --git a/src/Orchard.Web/Themes/TheAdmin/Styles/site.css b/src/Orchard.Web/Themes/TheAdmin/Styles/site.css
index 9a41675c6..77a6ce198 100644
--- a/src/Orchard.Web/Themes/TheAdmin/Styles/site.css
+++ b/src/Orchard.Web/Themes/TheAdmin/Styles/site.css
@@ -872,9 +872,9 @@ fieldset.save-button {
clear:left;
}
fieldset.publish-button {
- margin: 0 12px;
+ margin: 0 12px 0 0;
padding: 0 12px;
- border-left:1px solid #ccc;
+ border-right:1px solid #ccc;
}
fieldset.delete-button {
margin: 0 0 0 12px;
diff --git a/src/Orchard/Environment/Extensions/ExtensionLoaderCoordinator.cs b/src/Orchard/Environment/Extensions/ExtensionLoaderCoordinator.cs
index 138ca86a4..0c6360197 100644
--- a/src/Orchard/Environment/Extensions/ExtensionLoaderCoordinator.cs
+++ b/src/Orchard/Environment/Extensions/ExtensionLoaderCoordinator.cs
@@ -165,7 +165,7 @@ namespace Orchard.Environment.Extensions {
foreach(var dup in duplicates) {
sb.Append(T("Extension '{0}' has been found from the following locations: {1}.\r\n", dup.Key, string.Join(", ", dup.Select(e => e.Location + "/" + e.Id))));
}
- sb.Append(T("This issue can be usually by solved by removing or renaming the conflicting extension."));
+ sb.Append(T("This issue can be usually solved by removing or renaming the conflicting extension."));
Logger.Error(sb.ToString());
throw new OrchardException(new LocalizedString(sb.ToString()));
}