2010-01-21 16:54:00 +00:00
using System ;
using System.Collections.Generic ;
2010-04-02 15:17:13 -07:00
using Autofac ;
2010-01-21 16:54:00 +00:00
using JetBrains.Annotations ;
2010-01-18 17:40:06 +00:00
using NUnit.Framework ;
2010-01-21 16:54:00 +00:00
using Orchard.ContentManagement ;
using Orchard.ContentManagement.Drivers ;
using Orchard.ContentManagement.Handlers ;
using Orchard.ContentManagement.Records ;
using Orchard.Core.Common.Models ;
2010-01-18 17:40:06 +00:00
using Orchard.Core.Common.Services ;
2010-02-06 01:10:22 -08:00
using Orchard.Tests.Modules ;
2010-04-20 17:59:09 -07:00
using Orchard.Core.Common.Handlers ;
using System.Web.Mvc ;
using System.Web.Routing ;
using Orchard.Tests.Stubs ;
2010-01-18 17:40:06 +00:00
namespace Orchard.Core.Tests.Common.Services {
[TestFixture]
2010-01-21 16:54:00 +00:00
public class RoutableServiceTests : DatabaseEnabledTestsBase {
2010-01-18 17:40:06 +00:00
[SetUp]
2010-01-21 16:54:00 +00:00
public override void Init ( ) {
base . Init ( ) ;
_routableService = _container . Resolve < IRoutableService > ( ) ;
2010-01-18 17:40:06 +00:00
}
2010-01-21 16:54:00 +00:00
public override void Register ( ContainerBuilder builder ) {
2010-04-02 15:17:13 -07:00
builder . RegisterType < DefaultContentManager > ( ) . As < IContentManager > ( ) ;
2010-05-16 23:34:08 -07:00
builder . RegisterType < DefaultContentManagerSession > ( ) . As < IContentManagerSession > ( ) ;
2010-04-02 15:17:13 -07:00
builder . RegisterType < ThingHandler > ( ) . As < IContentHandler > ( ) ;
2010-04-20 17:59:09 -07:00
builder . RegisterType < StuffHandler > ( ) . As < IContentHandler > ( ) ;
2010-04-02 15:17:13 -07:00
builder . RegisterType < RoutableService > ( ) . As < IRoutableService > ( ) ;
2010-04-20 17:59:09 -07:00
builder . RegisterType < DefaultContentQuery > ( ) . As < IContentQuery > ( ) ;
builder . RegisterInstance ( new UrlHelper ( new RequestContext ( new StubHttpContext ( "~/" ) , new RouteData ( ) ) ) ) . As < UrlHelper > ( ) ;
builder . RegisterType < RoutableAspectHandler > ( ) . As < IContentHandler > ( ) ;
2010-01-21 16:54:00 +00:00
}
2010-01-18 17:40:06 +00:00
private IRoutableService _routableService ;
2010-01-21 16:54:00 +00:00
[Test]
public void InvalidCharactersShouldBeReplacedByADash ( ) {
var contentManager = _container . Resolve < IContentManager > ( ) ;
var thing = contentManager . Create < Thing > ( ThingDriver . ContentType . Name , t = > {
t . As < RoutableAspect > ( ) . Record = new RoutableRecord ( ) ;
t . Title = "Please do not use any of the following characters in your slugs: \":\", \"/\", \"?\", \"#\", \"[\", \"]\", \"@\", \"!\", \"$\", \"&\", \"'\", \"(\", \")\", \"*\", \"+\", \",\", \";\", \"=\"" ;
} ) ;
_routableService . FillSlug ( thing . As < RoutableAspect > ( ) ) ;
2010-01-27 07:12:27 +00:00
Assert . That ( thing . Slug , Is . EqualTo ( "please-do-not-use-any-of-the-following-characters-in-your-slugs-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"" ) ) ;
2010-01-21 16:54:00 +00:00
}
2010-04-21 10:01:57 -07:00
[Test]
public void EmptySlugsShouldBeConsideredValid ( ) {
// so that automatic generation on Publish occurs
Assert . That ( _routableService . IsSlugValid ( null ) , Is . True ) ;
Assert . That ( _routableService . IsSlugValid ( String . Empty ) , Is . True ) ;
Assert . That ( _routableService . IsSlugValid ( " " ) , Is . True ) ;
}
[Test]
public void InvalidCharacterShouldBeRefusedInSlugs ( ) {
Assert . That ( _routableService . IsSlugValid ( "aaaa-_aaaa" ) , Is . True ) ;
foreach ( var c in @"/:?#[]@!$&'()*+,;= " ) {
Assert . That ( _routableService . IsSlugValid ( "a" + c + "b" ) , Is . False ) ;
}
}
2010-05-16 23:34:08 -07:00
2010-04-21 10:01:57 -07:00
2010-01-21 16:54:00 +00:00
[Test]
public void VeryLongStringTruncatedTo1000Chars ( ) {
var contentManager = _container . Resolve < IContentManager > ( ) ;
2010-01-27 07:12:27 +00:00
var veryVeryLongTitle = "this is a very long title..." ;
2010-01-21 16:54:00 +00:00
for ( var i = 0 ; i < 100 ; i + + )
veryVeryLongTitle + = "aaaaaaaaaa" ;
var thing = contentManager . Create < Thing > ( ThingDriver . ContentType . Name , t = > {
t . As < RoutableAspect > ( ) . Record = new RoutableRecord ( ) ;
t . Title = veryVeryLongTitle ;
} ) ;
_routableService . FillSlug ( thing . As < RoutableAspect > ( ) ) ;
Assert . That ( veryVeryLongTitle . Length , Is . AtLeast ( 1001 ) ) ;
Assert . That ( thing . Slug . Length , Is . EqualTo ( 1000 ) ) ;
}
2010-01-22 22:25:52 +00:00
[Test]
public void NoExistingLikeSlugsGeneratesSameSlug ( ) {
string slug = _routableService . GenerateUniqueSlug ( "woohoo" , null ) ;
Assert . That ( slug , Is . EqualTo ( "woohoo" ) ) ;
}
[Test]
public void ExistingSingleLikeSlugThatsAConflictGeneratesADash2 ( ) {
string slug = _routableService . GenerateUniqueSlug ( "woohoo" , new List < string > { "woohoo" } ) ;
Assert . That ( slug , Is . EqualTo ( "woohoo-2" ) ) ;
}
[Test]
public void ExistingSingleLikeSlugThatsNotAConflictGeneratesSameSlug ( ) {
string slug = _routableService . GenerateUniqueSlug ( "woohoo" , new List < string > { "woohoo-2" } ) ;
Assert . That ( slug , Is . EqualTo ( "woohoo" ) ) ;
}
[Test]
public void ExistingLikeSlugsWithAConflictGeneratesADashVNext ( ) {
string slug = _routableService . GenerateUniqueSlug ( "woohoo" , new List < string > { "woohoo" , "woohoo-2" } ) ;
Assert . That ( slug , Is . EqualTo ( "woohoo-3" ) ) ;
}
[Test]
public void ExistingSlugsWithVersionGapsAndNoMatchGeneratesSameSlug ( ) {
string slug = _routableService . GenerateUniqueSlug ( "woohoo" , new List < string > { "woohoo-2" , "woohoo-4" , "woohoo-5" } ) ;
Assert . That ( slug , Is . EqualTo ( "woohoo" ) ) ;
}
[Test]
public void ExistingSlugsWithVersionGapsAndAMatchGeneratesADash2 ( ) {
string slug = _routableService . GenerateUniqueSlug ( "woohoo-2" , new List < string > { "woohoo-2" , "woohoo-4" , "woohoo-5" } ) ;
Assert . That ( slug , Is . EqualTo ( "woohoo-2-2" ) ) ;
}
2010-01-27 07:12:27 +00:00
[Test]
public void GeneratedSlugIsLowerCased ( ) {
var contentManager = _container . Resolve < IContentManager > ( ) ;
var thing = contentManager . Create < Thing > ( ThingDriver . ContentType . Name , t = > {
t . As < RoutableAspect > ( ) . Record = new RoutableRecord ( ) ;
t . Title = "This Is Some Interesting Title" ;
} ) ;
_routableService . FillSlug ( thing . As < RoutableAspect > ( ) ) ;
Assert . That ( thing . Slug , Is . EqualTo ( "this-is-some-interesting-title" ) ) ;
}
2010-04-20 17:59:09 -07:00
[Test]
2010-05-16 23:34:08 -07:00
public void GeneratedSlugsShouldBeUniqueAmongContentType ( ) {
2010-04-20 17:59:09 -07:00
var contentManager = _container . Resolve < IContentManager > ( ) ;
2010-05-16 23:34:08 -07:00
var thing1 = contentManager . Create < Thing > ( ThingDriver . ContentType . Name , t = > {
2010-04-20 17:59:09 -07:00
t . As < RoutableAspect > ( ) . Record = new RoutableRecord ( ) ;
t . Title = "This Is Some Interesting Title" ;
} ) ;
2010-05-16 23:34:08 -07:00
var thing2 = contentManager . Create < Thing > ( ThingDriver . ContentType . Name , t = > {
2010-04-20 17:59:09 -07:00
t . As < RoutableAspect > ( ) . Record = new RoutableRecord ( ) ;
t . Title = "This Is Some Interesting Title" ;
} ) ;
Assert . AreNotEqual ( thing1 . Slug , thing2 . Slug ) ;
}
[Test]
2010-05-16 23:34:08 -07:00
public void SlugsCanBeDuplicatedAccrossContentTypes ( ) {
2010-04-20 17:59:09 -07:00
var contentManager = _container . Resolve < IContentManager > ( ) ;
2010-05-16 23:34:08 -07:00
var thing = contentManager . Create < Thing > ( ThingDriver . ContentType . Name , t = > {
2010-04-20 17:59:09 -07:00
t . As < RoutableAspect > ( ) . Record = new RoutableRecord ( ) ;
t . Title = "This Is Some Interesting Title" ;
} ) ;
2010-05-16 23:34:08 -07:00
var stuff = contentManager . Create < Stuff > ( StuffDriver . ContentType . Name , s = > {
2010-04-20 17:59:09 -07:00
s . As < RoutableAspect > ( ) . Record = new RoutableRecord ( ) ;
s . Title = "This Is Some Interesting Title" ;
} ) ;
Assert . AreEqual ( thing . Slug , stuff . Slug ) ;
}
2010-01-21 16:54:00 +00:00
protected override IEnumerable < Type > DatabaseTypes {
get {
return new [ ] {
typeof ( RoutableRecord ) ,
2010-05-20 11:00:44 -07:00
typeof ( ContentTypeRecord ) ,
2010-01-21 16:54:00 +00:00
typeof ( ContentItemRecord ) ,
typeof ( ContentItemVersionRecord ) ,
typeof ( CommonRecord ) ,
typeof ( CommonVersionRecord ) ,
} ;
}
}
[UsedImplicitly]
public class ThingHandler : ContentHandler {
2010-05-16 23:34:08 -07:00
public ThingHandler ( ) {
2010-01-21 16:54:00 +00:00
Filters . Add ( new ActivatingFilter < Thing > ( ThingDriver . ContentType . Name ) ) ;
Filters . Add ( new ActivatingFilter < ContentPart < CommonVersionRecord > > ( ThingDriver . ContentType . Name ) ) ;
Filters . Add ( new ActivatingFilter < CommonAspect > ( ThingDriver . ContentType . Name ) ) ;
Filters . Add ( new ActivatingFilter < RoutableAspect > ( ThingDriver . ContentType . Name ) ) ;
}
}
public class Thing : ContentPart {
public int Id { get { return ContentItem . Id ; } }
public string Title {
get { return this . As < RoutableAspect > ( ) . Title ; }
set { this . As < RoutableAspect > ( ) . Title = value ; }
}
public string Slug {
get { return this . As < RoutableAspect > ( ) . Slug ; }
set { this . As < RoutableAspect > ( ) . Slug = value ; }
}
}
2010-05-16 23:34:08 -07:00
2010-01-21 16:54:00 +00:00
public class ThingDriver : ContentItemDriver < Thing > {
public readonly static ContentType ContentType = new ContentType {
Name = "thing" ,
DisplayName = "Thing"
} ;
}
2010-04-20 17:59:09 -07:00
[UsedImplicitly]
2010-05-16 23:34:08 -07:00
public class StuffHandler : ContentHandler {
public StuffHandler ( ) {
2010-04-20 17:59:09 -07:00
Filters . Add ( new ActivatingFilter < Stuff > ( StuffDriver . ContentType . Name ) ) ;
Filters . Add ( new ActivatingFilter < ContentPart < CommonVersionRecord > > ( StuffDriver . ContentType . Name ) ) ;
Filters . Add ( new ActivatingFilter < CommonAspect > ( StuffDriver . ContentType . Name ) ) ;
Filters . Add ( new ActivatingFilter < RoutableAspect > ( StuffDriver . ContentType . Name ) ) ;
}
}
2010-05-16 23:34:08 -07:00
public class Stuff : ContentPart {
2010-04-20 17:59:09 -07:00
public int Id { get { return ContentItem . Id ; } }
2010-05-16 23:34:08 -07:00
public string Title {
2010-04-20 17:59:09 -07:00
get { return this . As < RoutableAspect > ( ) . Title ; }
set { this . As < RoutableAspect > ( ) . Title = value ; }
}
2010-05-16 23:34:08 -07:00
public string Slug {
2010-04-20 17:59:09 -07:00
get { return this . As < RoutableAspect > ( ) . Slug ; }
set { this . As < RoutableAspect > ( ) . Slug = value ; }
}
}
2010-05-16 23:34:08 -07:00
public class StuffDriver : ContentItemDriver < Stuff > {
public readonly static ContentType ContentType = new ContentType {
2010-04-20 17:59:09 -07:00
Name = "stuff" ,
DisplayName = "Stuff"
} ;
}
2010-01-18 17:40:06 +00:00
}
}