diff --git a/src/Umbraco.Tests/Migrations/AdvancedMigrationTests.cs b/src/Umbraco.Tests/Migrations/AdvancedMigrationTests.cs index 33185b694a..5505d7ecd7 100644 --- a/src/Umbraco.Tests/Migrations/AdvancedMigrationTests.cs +++ b/src/Umbraco.Tests/Migrations/AdvancedMigrationTests.cs @@ -41,7 +41,7 @@ namespace Umbraco.Tests.Migrations upgrader.Execute(); var helper = new DatabaseSchemaCreator(scope.Database, logger); - var exists = helper.TableExists("umbracoNode"); + var exists = helper.TableExists("umbracoUser"); Assert.IsTrue(exists); scope.Complete(); @@ -194,8 +194,8 @@ namespace Umbraco.Tests.Migrations public override void Migrate() { - // creates Node table with keys, indexes, etc - Create.Table().Do(); + // creates User table with keys, indexes, etc + Create.Table().Do(); } } @@ -207,8 +207,8 @@ namespace Umbraco.Tests.Migrations public override void Migrate() { - // drops Node table keys and indexes - //Execute.DropKeysAndIndexes("umbracoNode"); + // drops User table keys and indexes + //Execute.DropKeysAndIndexes("umbracoUser"); // drops *all* tables keys and indexes Delete.KeysAndIndexes().Do(); @@ -224,7 +224,7 @@ namespace Umbraco.Tests.Migrations public override void Migrate() { // creates Node table keys and indexes - Create.KeysAndIndexes().Do(); + Create.KeysAndIndexes().Do(); } } @@ -240,7 +240,7 @@ namespace Umbraco.Tests.Migrations foreach (var x in DatabaseSchemaCreator.OrderedTables) { // ok - for tests, restrict to Node - if (x != typeof(NodeDto)) continue; + if (x != typeof(UserDto)) continue; Create.KeysAndIndexes(x).Do(); } @@ -258,12 +258,12 @@ namespace Umbraco.Tests.Migrations // cannot delete the column without this, of course Delete.KeysAndIndexes().Do(); - Delete.Column("id").FromTable("umbracoNode").Do(); + Delete.Column("id").FromTable("umbracoUser").Do(); - var table = DefinitionFactory.GetTableDefinition(typeof(NodeDto), SqlSyntax); + var table = DefinitionFactory.GetTableDefinition(typeof(UserDto), SqlSyntax); var column = table.Columns.First(x => x.Name == "id"); var create = SqlSyntax.Format(column); // returns [id] INTEGER NOT NULL IDENTITY(1060,1) - Database.Execute($"ALTER TABLE {SqlSyntax.GetQuotedTableName("umbracoNode")} ADD " + create); + Database.Execute($"ALTER TABLE {SqlSyntax.GetQuotedTableName("umbracoUser")} ADD " + create); } } } diff --git a/src/Umbraco.Tests/Persistence/Repositories/DataTypeDefinitionRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/DataTypeDefinitionRepositoryTest.cs index cc515c4347..56cdac04e8 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/DataTypeDefinitionRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/DataTypeDefinitionRepositoryTest.cs @@ -217,7 +217,7 @@ namespace Umbraco.Tests.Persistence.Repositories Assert.That(dataTypeDefinitions, Is.Not.Null); Assert.That(dataTypeDefinitions.Any(), Is.True); Assert.That(dataTypeDefinitions.Any(x => x == null), Is.False); - Assert.That(dataTypeDefinitions.Length, Is.EqualTo(24)); + Assert.That(dataTypeDefinitions.Length, Is.EqualTo(29)); } } diff --git a/src/Umbraco.Tests/Routing/ContentFinderByAliasTests.cs b/src/Umbraco.Tests/Routing/ContentFinderByAliasTests.cs index 09ee0346fb..e59fad6117 100644 --- a/src/Umbraco.Tests/Routing/ContentFinderByAliasTests.cs +++ b/src/Umbraco.Tests/Routing/ContentFinderByAliasTests.cs @@ -1,4 +1,10 @@ -using NUnit.Framework; +using System.Linq; +using Moq; +using NUnit.Framework; +using Umbraco.Core; +using Umbraco.Core.Models; +using Umbraco.Core.Models.PublishedContent; +using Umbraco.Core.PropertyEditors; using Umbraco.Web.Routing; namespace Umbraco.Tests.Routing @@ -8,6 +14,28 @@ namespace Umbraco.Tests.Routing [TestFixture] public class ContentFinderByAliasTests : UrlRoutingTestBase { + private PublishedContentType _publishedContentType; + + protected override void Initialize() + { + base.Initialize(); + + var properties = new[] + { + new PublishedPropertyType("umbracoUrlAlias", Constants.DataTypes.Textbox, false, ContentVariation.InvariantNeutral, + new PropertyValueConverterCollection(Enumerable.Empty()), + Mock.Of(), + Mock.Of()), + }; + _publishedContentType = new PublishedContentType(0, "Doc", PublishedItemType.Content, Enumerable.Empty(), properties, ContentVariation.InvariantNeutral); + } + + protected override PublishedContentType GetPublishedContentTypeByAlias(string alias) + { + if (alias == "Doc") return _publishedContentType; + return null; + } + [TestCase("/this/is/my/alias", 1001)] [TestCase("/anotheralias", 1001)] [TestCase("/page2/alias", 10011)] diff --git a/src/Umbraco.Tests/Routing/ContentFinderByAliasWithDomainsTests.cs b/src/Umbraco.Tests/Routing/ContentFinderByAliasWithDomainsTests.cs index 5992463296..2173990f76 100644 --- a/src/Umbraco.Tests/Routing/ContentFinderByAliasWithDomainsTests.cs +++ b/src/Umbraco.Tests/Routing/ContentFinderByAliasWithDomainsTests.cs @@ -1,12 +1,39 @@ -using NUnit.Framework; +using System.Linq; +using Moq; +using NUnit.Framework; +using Umbraco.Core; +using Umbraco.Core.Models; +using Umbraco.Core.Models.PublishedContent; +using Umbraco.Core.PropertyEditors; using Umbraco.Web.Routing; namespace Umbraco.Tests.Routing { - [TestFixture] public class ContentFinderByAliasWithDomainsTests : ContentFinderByAliasTests { + private PublishedContentType _publishedContentType; + + protected override void Initialize() + { + base.Initialize(); + + var properties = new[] + { + new PublishedPropertyType("umbracoUrlAlias", Constants.DataTypes.Textbox, false, ContentVariation.InvariantNeutral, + new PropertyValueConverterCollection(Enumerable.Empty()), + Mock.Of(), + Mock.Of()), + }; + _publishedContentType = new PublishedContentType(0, "Doc", PublishedItemType.Content, Enumerable.Empty(), properties, ContentVariation.InvariantNeutral); + } + + protected override PublishedContentType GetPublishedContentTypeByAlias(string alias) + { + if (alias == "Doc") return _publishedContentType; + return null; + } + [TestCase("http://domain1.com/this/is/my/alias", "de-DE", -1001)] // alias to domain's page fails - no alias on domain's home [TestCase("http://domain1.com/page2/alias", "de-DE", 10011)] // alias to sub-page works [TestCase("http://domain1.com/en/flux", "en-US", -10011)] // alias to domain's page fails - no alias on domain's home diff --git a/src/Umbraco.Tests/Services/ContentServiceTests.cs b/src/Umbraco.Tests/Services/ContentServiceTests.cs index 34cab4f970..0326ce0a15 100644 --- a/src/Umbraco.Tests/Services/ContentServiceTests.cs +++ b/src/Umbraco.Tests/Services/ContentServiceTests.cs @@ -24,8 +24,8 @@ using Umbraco.Core.Scoping; using Umbraco.Core.Services.Implement; using Umbraco.Tests.Testing; using Umbraco.Web.PropertyEditors; -using System.Reflection; - +using System.Reflection; + namespace Umbraco.Tests.Services { /// @@ -59,32 +59,32 @@ namespace Umbraco.Tests.Services // fixme - do it differently Container.Register(factory => factory.GetInstance().TextService); } - + /// /// Used to list out all ambiguous events that will require dispatching with a name - /// - [Test] - public void List_Ambiguous_Events() - { - var events = ServiceContext.ContentService.GetType().GetEvents(BindingFlags.Static | BindingFlags.Public); - var typedEventHandler = typeof(TypedEventHandler<,>); - foreach(var e in events) - { - //only continue if this is a TypedEventHandler - if (!e.EventHandlerType.IsGenericType) continue; - var typeDef = e.EventHandlerType.GetGenericTypeDefinition(); - if (typedEventHandler != typeDef) continue; - - //get the event arg type - var eventArgType = e.EventHandlerType.GenericTypeArguments[1]; - - var found = EventNameExtractor.FindEvent(typeof(ContentService), eventArgType, EventNameExtractor.MatchIngNames); - if (!found.Success && found.Result.Error == EventNameExtractorError.Ambiguous) - { - Console.WriteLine($"Ambiguous event, source: {typeof(ContentService)}, args: {eventArgType}"); - } - } - } + /// + [Test] + public void List_Ambiguous_Events() + { + var events = ServiceContext.ContentService.GetType().GetEvents(BindingFlags.Static | BindingFlags.Public); + var typedEventHandler = typeof(TypedEventHandler<,>); + foreach(var e in events) + { + //only continue if this is a TypedEventHandler + if (!e.EventHandlerType.IsGenericType) continue; + var typeDef = e.EventHandlerType.GetGenericTypeDefinition(); + if (typedEventHandler != typeDef) continue; + + //get the event arg type + var eventArgType = e.EventHandlerType.GenericTypeArguments[1]; + + var found = EventNameExtractor.FindEvent(typeof(ContentService), eventArgType, EventNameExtractor.MatchIngNames); + if (!found.Success && found.Result.Error == EventNameExtractorError.Ambiguous) + { + Console.WriteLine($"Ambiguous event, source: {typeof(ContentService)}, args: {eventArgType}"); + } + } + } [Test] public void Create_Blueprint() @@ -2499,78 +2499,78 @@ namespace Umbraco.Tests.Services contentService.Save(content); // this is effectively a rollback? contentService.Rollback(content); // just kill the method and offer options on values + template + name... */ - } - + } + [Test] public void Ensure_Invariant_Name() - { + { var languageService = ServiceContext.LocalizationService; - - var langUk = new Language("en-UK") { IsDefaultVariantLanguage = true }; + + var langUk = new Language("en-UK") { IsDefaultVariantLanguage = true }; var langFr = new Language("fr-FR"); languageService.Save(langFr); languageService.Save(langUk); - var contentTypeService = ServiceContext.ContentTypeService; - + var contentTypeService = ServiceContext.ContentTypeService; + var contentType = contentTypeService.Get("umbTextpage"); contentType.Variations = ContentVariation.InvariantNeutral | ContentVariation.CultureNeutral; contentType.AddPropertyType(new PropertyType(Constants.PropertyEditors.Aliases.TextBox, ValueStorageType.Nvarchar, "prop") { Variations = ContentVariation.CultureNeutral }); contentTypeService.Save(contentType); var contentService = ServiceContext.ContentService; - var content = new Content(null, -1, contentType); + var content = new Content(null, -1, contentType); - content.SetName("name-us", langUk.IsoCode); + content.SetName("name-us", langUk.IsoCode); content.SetName("name-fr", langFr.IsoCode); - contentService.Save(content); - - //the name will be set to the default culture variant name - Assert.AreEqual("name-us", content.Name); - - //fixme - should we always sync the invariant name even on update? see EnsureInvariantNameValues - ////updating the default culture variant name should also update the invariant name so they stay in sync - //content.SetName("name-us-2", langUk.IsoCode); - //contentService.Save(content); - //Assert.AreEqual("name-us-2", content.Name); - } - + contentService.Save(content); + + //the name will be set to the default culture variant name + Assert.AreEqual("name-us", content.Name); + + //fixme - should we always sync the invariant name even on update? see EnsureInvariantNameValues + ////updating the default culture variant name should also update the invariant name so they stay in sync + //content.SetName("name-us-2", langUk.IsoCode); + //contentService.Save(content); + //Assert.AreEqual("name-us-2", content.Name); + } + [Test] public void Ensure_Unique_Culture_Names() - { + { var languageService = ServiceContext.LocalizationService; - - var langUk = new Language("en-UK") { IsDefaultVariantLanguage = true }; - var langFr = new Language("fr-FR"); - + + var langUk = new Language("en-UK") { IsDefaultVariantLanguage = true }; + var langFr = new Language("fr-FR"); + languageService.Save(langFr); languageService.Save(langUk); - var contentTypeService = ServiceContext.ContentTypeService; - + var contentTypeService = ServiceContext.ContentTypeService; + var contentType = contentTypeService.Get("umbTextpage"); contentType.Variations = ContentVariation.InvariantNeutral | ContentVariation.CultureNeutral; contentType.AddPropertyType(new PropertyType(Constants.PropertyEditors.Aliases.TextBox, ValueStorageType.Nvarchar, "prop") { Variations = ContentVariation.CultureNeutral }); contentTypeService.Save(contentType); - var contentService = ServiceContext.ContentService; + var contentService = ServiceContext.ContentService; var content = new Content(null, -1, contentType); content.SetName("root", langUk.IsoCode); - contentService.Save(content); - - for (var i = 0; i < 5; i++) - { - var child = new Content(null, content, contentType); - child.SetName("child", langUk.IsoCode); - contentService.Save(child); - Assert.AreEqual("child" + (i == 0 ? "" : " (" + (i).ToString() + ")"), child.GetName(langUk.IsoCode)); - - //Save it again to ensure that the unique check is not performed again against it's own name - contentService.Save(child); - Assert.AreEqual("child" + (i == 0 ? "" : " (" + (i).ToString() + ")"), child.GetName(langUk.IsoCode)); - } + contentService.Save(content); + + for (var i = 0; i < 5; i++) + { + var child = new Content(null, content, contentType); + child.SetName("child", langUk.IsoCode); + contentService.Save(child); + Assert.AreEqual("child" + (i == 0 ? "" : " (" + (i).ToString() + ")"), child.GetName(langUk.IsoCode)); + + //Save it again to ensure that the unique check is not performed again against it's own name + contentService.Save(child); + Assert.AreEqual("child" + (i == 0 ? "" : " (" + (i).ToString() + ")"), child.GetName(langUk.IsoCode)); + } } [Test] @@ -2661,10 +2661,10 @@ namespace Umbraco.Tests.Services Assert.AreEqual("name-fr", content2.GetName(langFr.IsoCode)); Assert.AreEqual("name-uk", content2.GetName(langUk.IsoCode)); - // we haven't published InvariantNeutral, but a document cannot be published without an invariant name, - // so when we tried and published for the first time above the french culture, the french name was used - // to populate the invariant name - Assert.AreEqual("name-fr", content2.PublishName); + // we haven't published InvariantNeutral, but a document cannot be published without an invariant name, + // so when we tried and published for the first time above the french culture, the french name was used + // to populate the invariant name + Assert.AreEqual("name-fr", content2.PublishName); Assert.AreEqual("name-fr", content2.GetPublishName(langFr.IsoCode)); Assert.AreEqual("name-uk", content2.GetPublishName(langUk.IsoCode)); @@ -2685,10 +2685,10 @@ namespace Umbraco.Tests.Services // fr and uk, published without changes, not edited AssertPerCulture(content, (x, c) => x.IsCultureEdited(c), (langFr, false), (langUk, false), (langDe, true)); AssertPerCulture(content2, (x, c) => x.IsCultureEdited(c), (langFr, false), (langUk, false), (langDe, true)); - + AssertPerCulture(content, (x, c) => x.GetCulturePublishDate(c) == DateTime.MinValue, (langFr, false), (langUk, false)); // DE would throw AssertPerCulture(content2, (x, c) => x.GetCulturePublishDate(c) == DateTime.MinValue, (langFr, false), (langUk, false)); // DE would throw - + // note that content and content2 culture published dates might be slightly different due to roundtrip to database @@ -2702,7 +2702,7 @@ namespace Umbraco.Tests.Services content2 = contentService.GetById(content.Id); Assert.AreEqual("Home US", content2.PublishName); - + // act @@ -2742,14 +2742,14 @@ namespace Umbraco.Tests.Services // no change AssertPerCulture(content, (x, c) => x.IsCulturePublished(c), (langFr, true), (langUk, true), (langDe, false)); AssertPerCulture(content2, (x, c) => x.IsCulturePublished(c), (langFr, true), (langUk, true), (langDe, false)); - + // we have changed values so now fr and uk are edited AssertPerCulture(content, (x, c) => x.IsCultureEdited(c), (langFr, true), (langUk, true), (langDe, true)); AssertPerCulture(content2, (x, c) => x.IsCultureEdited(c), (langFr, true), (langUk, true), (langDe, true)); AssertPerCulture(content, (x, c) => x.GetCulturePublishDate(c) == DateTime.MinValue, (langFr, false), (langUk, false)); // DE would throw AssertPerCulture(content2, (x, c) => x.GetCulturePublishDate(c) == DateTime.MinValue, (langFr, false), (langUk, false)); // DE would throw - + // act // cannot just 'save' since we are changing what's published! @@ -2792,8 +2792,8 @@ namespace Umbraco.Tests.Services AssertPerCulture(content, (x, c) => x.GetCulturePublishDate(c) == DateTime.MinValue, (langUk, false)); // FR, DE would throw AssertPerCulture(content2, (x, c) => x.GetCulturePublishDate(c) == DateTime.MinValue, (langUk, false)); // FR, DE would throw - - + + // act contentService.Unpublish(content); @@ -2839,7 +2839,7 @@ namespace Umbraco.Tests.Services AssertPerCulture(content, (x, c) => x.GetCulturePublishDate(c) == DateTime.MinValue, (langUk, false)); // FR, DE would throw AssertPerCulture(content2, (x, c) => x.GetCulturePublishDate(c) == DateTime.MinValue, (langUk, false)); // FR, DE would throw - + // act @@ -2878,9 +2878,9 @@ namespace Umbraco.Tests.Services AssertPerCulture(content2, (x, c) => x.IsCultureEdited(c), (langFr, true), (langUk, true), (langDe, true)); AssertPerCulture(content, (x, c) => x.GetCulturePublishDate(c) == DateTime.MinValue, (langUk, false)); // FR, DE would throw - AssertPerCulture(content2, (x, c) => x.GetCulturePublishDate(c) == DateTime.MinValue, (langUk, false)); // FR, DE would throw - - + AssertPerCulture(content2, (x, c) => x.GetCulturePublishDate(c) == DateTime.MinValue, (langUk, false)); // FR, DE would throw + + // act content.TryPublishValues(langUk.IsoCode); @@ -2901,17 +2901,17 @@ namespace Umbraco.Tests.Services AssertPerCulture(content2, (x, c) => x.IsCultureEdited(c), (langFr, true), (langUk, false), (langDe, true)); AssertPerCulture(content, (x, c) => x.GetCulturePublishDate(c) == DateTime.MinValue, (langUk, false)); // FR, DE would throw - AssertPerCulture(content2, (x, c) => x.GetCulturePublishDate(c) == DateTime.MinValue, (langUk, false)); // FR, DE would throw - - - // act - + AssertPerCulture(content2, (x, c) => x.GetCulturePublishDate(c) == DateTime.MinValue, (langUk, false)); // FR, DE would throw + + + // act + content.SetName("name-uk3", langUk.IsoCode); contentService.Save(content); content2 = contentService.GetById(content.Id); - - // changing the name = edited! + + // changing the name = edited! Assert.IsTrue(content.IsCultureEdited(langUk.IsoCode)); Assert.IsTrue(content2.IsCultureEdited(langUk.IsoCode)); } @@ -2963,7 +2963,7 @@ namespace Umbraco.Tests.Services var accessor = (IScopeAccessor) provider; var templateRepository = new TemplateRepository(accessor, DisabledCache, Logger, Mock.Of(), Mock.Of(), Mock.Of()); var tagRepository = new TagRepository(accessor, DisabledCache, Logger); - contentTypeRepository = new ContentTypeRepository(accessor, DisabledCache, Logger, templateRepository); + contentTypeRepository = new ContentTypeRepository(accessor, DisabledCache, Logger, templateRepository); var languageRepository = new LanguageRepository(accessor, DisabledCache, Logger); var repository = new DocumentRepository(accessor, DisabledCache, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository, Mock.Of()); return repository; diff --git a/src/Umbraco.Tests/TestHelpers/BaseWebTest.cs b/src/Umbraco.Tests/TestHelpers/BaseWebTest.cs index 8008253db4..d99fde9ca3 100644 --- a/src/Umbraco.Tests/TestHelpers/BaseWebTest.cs +++ b/src/Umbraco.Tests/TestHelpers/BaseWebTest.cs @@ -5,6 +5,7 @@ using System.Threading; using LightInject; using Moq; using NUnit.Framework; +using Umbraco.Core.Composing; using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.Logging; using Umbraco.Core.Models; @@ -14,6 +15,7 @@ using Umbraco.Core.Services; using Umbraco.Tests.PublishedContent; using Umbraco.Tests.TestHelpers.Stubs; using Umbraco.Tests.Testing.Objects.Accessors; +using Umbraco.Web.Models.PublishedContent; using Umbraco.Web.Routing; namespace Umbraco.Tests.TestHelpers @@ -22,6 +24,14 @@ namespace Umbraco.Tests.TestHelpers [Apartment(ApartmentState.STA)] public abstract class BaseWebTest : TestWithDatabaseBase { + protected override void Compose() + { + base.Compose(); + + Container.RegisterSingleton(); + Container.RegisterSingleton(); + } + protected override void Initialize() { base.Initialize(); @@ -34,9 +44,11 @@ namespace Umbraco.Tests.TestHelpers var factory = new PublishedContentTypeFactory(Mock.Of(), new PropertyValueConverterCollection(Array.Empty()), dataTypeService); var type = new AutoPublishedContentType(0, "anything", new PublishedPropertyType[] { }); - ContentTypesCache.GetPublishedContentTypeByAlias = alias => type; + ContentTypesCache.GetPublishedContentTypeByAlias = alias => GetPublishedContentTypeByAlias(alias) ?? type; } + protected virtual PublishedContentType GetPublishedContentTypeByAlias(string alias) => null; + protected override string GetXmlContent(int templateId) { return @" diff --git a/src/Umbraco.Web/Routing/ContentFinderByUrlAlias.cs b/src/Umbraco.Web/Routing/ContentFinderByUrlAlias.cs index 1ab925e8f1..678d7bc2b4 100644 --- a/src/Umbraco.Web/Routing/ContentFinderByUrlAlias.cs +++ b/src/Umbraco.Web/Routing/ContentFinderByUrlAlias.cs @@ -78,7 +78,9 @@ namespace Umbraco.Web.Routing // ")]" if (!c.HasProperty(propertyAlias)) return false; - var v = "," + c.Value(propertyAlias).Replace(" ", "") + ","; + var v = c.Value(propertyAlias); + if (string.IsNullOrWhiteSpace(v)) return false; + v = "," + v.Replace(" ", "") + ","; return v.Contains(a1) || v.Contains(a2); }