Merge remote-tracking branch 'refs/remotes/umbraco/dev-v7' into dev-v7

This commit is contained in:
bjarnef
2016-03-03 17:58:36 +01:00
117 changed files with 2259 additions and 1502 deletions

View File

@@ -175,8 +175,8 @@
<!-- Copy SQL CE -->
<ItemGroup>
<SQLCE4Files
Include="..\src\packages\SqlServerCE.4.0.0.0\**\*.*"
Exclude="..\src\packages\SqlServerCE.4.0.0.0\lib\**\*;..\src\packages\SqlServerCE.4.0.0.0\**\*.nu*"
Include="..\src\packages\SqlServerCE.4.0.0.1\**\*.*"
Exclude="..\src\packages\SqlServerCE.4.0.0.1\lib\**\*;..\src\packages\SqlServerCE.4.0.0.1\**\*.nu*"
/>
</ItemGroup>

View File

@@ -1,2 +1,2 @@
# Usage: on line 2 put the release version, on line 3 put the version comment (example: beta)
7.4.0
7.4.1

View File

@@ -47,13 +47,15 @@
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Data.SqlServerCe, Version=4.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<Private>True</Private>
<HintPath>..\packages\SqlServerCE.4.0.0.0\lib\System.Data.SqlServerCe.dll</HintPath>
<Reference Include="System.Data.SqlServerCe, Version=4.0.0.1, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<HintPath>..\packages\SqlServerCE.4.0.0.1\lib\System.Data.SqlServerCe.dll</HintPath>
<SpecificVersion>False</SpecificVersion>
<Private>False</Private>
</Reference>
<Reference Include="System.Data.SqlServerCe.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<Private>True</Private>
<HintPath>..\packages\SqlServerCE.4.0.0.0\lib\System.Data.SqlServerCe.Entity.dll</HintPath>
<Reference Include="System.Data.SqlServerCe.Entity, Version=4.0.0.1, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<HintPath>..\packages\SqlServerCE.4.0.0.1\lib\System.Data.SqlServerCe.Entity.dll</HintPath>
<SpecificVersion>False</SpecificVersion>
<Private>False</Private>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />

View File

@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="SqlServerCE" version="4.0.0.0" targetFramework="net40" />
<package id="SqlServerCE" version="4.0.0.1" targetFramework="net45" />
</packages>

View File

@@ -11,5 +11,5 @@ using System.Resources;
[assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyFileVersion("7.4.0")]
[assembly: AssemblyInformationalVersion("7.4.0")]
[assembly: AssemblyFileVersion("7.4.1")]
[assembly: AssemblyInformationalVersion("7.4.1")]

View File

@@ -6,7 +6,7 @@ namespace Umbraco.Core.Configuration
{
public class UmbracoVersion
{
private static readonly Version Version = new Version("7.4.0");
private static readonly Version Version = new Version("7.4.1");
/// <summary>
/// Gets the current version of Umbraco.

View File

@@ -10,6 +10,12 @@ namespace Umbraco.Core
/// </summary>
public static class Web
{
public const string UmbracoContextDataToken = "umbraco-context";
public const string UmbracoDataToken = "umbraco";
public const string PublishedDocumentRequestDataToken = "umbraco-doc-request";
public const string CustomRouteDataToken = "umbraco-custom-route";
public const string UmbracoRouteDefinitionDataToken = "umbraco-route-def";
/// <summary>
/// The preview cookie name
/// </summary>

View File

@@ -1,9 +1,6 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Web.Caching;
using System.Web.UI;
using Umbraco.Core.Cache;
namespace Umbraco.Core.Models.PublishedContent
@@ -16,6 +13,7 @@ namespace Umbraco.Core.Models.PublishedContent
public class PublishedContentType
{
private readonly PublishedPropertyType[] _propertyTypes;
private readonly HashSet<string> _compositionAliases;
// fast alias-to-index xref containing both the raw alias and its lowercase version
private readonly Dictionary<string, int> _indexes = new Dictionary<string, int>();
@@ -27,6 +25,7 @@ namespace Umbraco.Core.Models.PublishedContent
{
Id = contentType.Id;
Alias = contentType.Alias;
_compositionAliases = new HashSet<string>(contentType.CompositionAliases(), StringComparer.InvariantCultureIgnoreCase);
_propertyTypes = contentType.CompositionPropertyTypes
.Select(x => new PublishedPropertyType(this, x))
.ToArray();
@@ -34,10 +33,11 @@ namespace Umbraco.Core.Models.PublishedContent
}
// internal so it can be used for unit tests
internal PublishedContentType(int id, string alias, IEnumerable<PublishedPropertyType> propertyTypes)
internal PublishedContentType(int id, string alias, IEnumerable<string> compositionAliases, IEnumerable<PublishedPropertyType> propertyTypes)
{
Id = id;
Alias = alias;
_compositionAliases = new HashSet<string>(compositionAliases, StringComparer.InvariantCultureIgnoreCase);
_propertyTypes = propertyTypes.ToArray();
foreach (var propertyType in _propertyTypes)
propertyType.ContentType = this;
@@ -45,8 +45,8 @@ namespace Umbraco.Core.Models.PublishedContent
}
// create detached content type - ie does not match anything in the DB
internal PublishedContentType(string alias, IEnumerable<PublishedPropertyType> propertyTypes)
: this (0, alias, propertyTypes)
internal PublishedContentType(string alias, IEnumerable<string> compositionAliases, IEnumerable<PublishedPropertyType> propertyTypes)
: this(0, alias, compositionAliases, propertyTypes)
{ }
private void InitializeIndexes()
@@ -63,6 +63,7 @@ namespace Umbraco.Core.Models.PublishedContent
public int Id { get; private set; }
public string Alias { get; private set; }
public HashSet<string> CompositionAliases { get { return _compositionAliases; } }
#endregion

View File

@@ -20,7 +20,17 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenFourZer
if (columns.Any(x => x.TableName.InvariantEquals("cmsPropertyTypeGroup") && x.ColumnName.InvariantEquals("parentGroupId")) == false)
return;
Delete.ForeignKey("FK_cmsPropertyTypeGroup_cmsPropertyTypeGroup_id").OnTable("cmsPropertyTypeGroup");
//This constraing can be based on old aliases, before removing them, check they exist
var constraints = SqlSyntax.GetConstraintsPerColumn(Context.Database).Distinct().ToArray();
if (constraints.Any(x => x.Item1.InvariantEquals("cmsPropertyTypeGroup") && x.Item3.InvariantEquals("FK_cmsPropertyTypeGroup_cmsPropertyTypeGroup_id")))
{
Delete.ForeignKey("FK_cmsPropertyTypeGroup_cmsPropertyTypeGroup_id").OnTable("cmsPropertyTypeGroup");
}
if (constraints.Any(x => x.Item1.InvariantEquals("cmsPropertyTypeGroup") && x.Item3.InvariantEquals("FK_cmsPropertyTypeGroup_cmsPropertyTypeGroup")))
{
Delete.ForeignKey("FK_cmsPropertyTypeGroup_cmsPropertyTypeGroup").OnTable("cmsPropertyTypeGroup");
}
Delete.Column("parentGroupId").FromTable("cmsPropertyTypeGroup");
}

View File

@@ -28,6 +28,8 @@ namespace Umbraco.Core.Persistence.SqlSyntax
GuidColumnDefinition = "char(36)";
DefaultValueFormat = "DEFAULT {0}";
InitColumnTypeMap();
}
public override IEnumerable<string> GetTablesInSchema(Database db)

View File

@@ -0,0 +1,28 @@
using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Core.PropertyEditors.ValueConverters
{
/// <summary>
/// We need this property converter so that we always force the value of a label to be a string
/// </summary>
/// <remarks>
/// Without a property converter defined for the label type, the value will be converted with
/// the `ConvertUsingDarkMagic` method which will try to parse the value into it's correct type, but this
/// can cause issues if the string is detected as a number and then strips leading zeros.
/// Example: http://issues.umbraco.org/issue/U4-7929
/// </remarks>
[DefaultPropertyValueConverter]
[PropertyValueType(typeof (string))]
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
public class LabelValueConverter : PropertyValueConverterBase
{
public override bool IsConverter(PublishedPropertyType propertyType)
{
return Constants.PropertyEditors.NoEditAlias.Equals(propertyType.PropertyEditorAlias);
}
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
{
return source == null ? string.Empty : source.ToString();
}
}
}

View File

@@ -255,7 +255,12 @@ namespace Umbraco.Core.Services
/// </returns>
public Attempt<OperationStatus<ITemplate, OperationStatusType>> CreateTemplateForContentType(string contentTypeAlias, string contentTypeName, int userId = 0)
{
var template = new Template(contentTypeName, contentTypeAlias);
var template = new Template(contentTypeName,
//NOTE: We are NOT passing in the content type alias here, we want to use it's name since we don't
// want to save template file names as camelCase, the Template ctor will clean the alias as
// `alias.ToCleanString(CleanStringType.UnderscoreAlias)` which has been the default.
// This fixes: http://issues.umbraco.org/issue/U4-7953
contentTypeName);
var evtMsgs = EventMessagesFactory.Get();

View File

@@ -102,13 +102,13 @@
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Configuration" />
<Reference Include="System.Data.Entity" />
<Reference Include="System.Data.SqlServerCe, Version=4.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<Reference Include="System.Data.SqlServerCe, Version=4.0.0.1, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\SqlServerCE.4.0.0.0\lib\System.Data.SqlServerCe.dll</HintPath>
<HintPath>..\packages\SqlServerCE.4.0.0.1\lib\System.Data.SqlServerCe.dll</HintPath>
</Reference>
<Reference Include="System.Data.SqlServerCe.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<Reference Include="System.Data.SqlServerCe.Entity, Version=4.0.0.1, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\SqlServerCE.4.0.0.0\lib\System.Data.SqlServerCe.Entity.dll</HintPath>
<HintPath>..\packages\SqlServerCE.4.0.0.1\lib\System.Data.SqlServerCe.Entity.dll</HintPath>
</Reference>
<Reference Include="System.Drawing" />
<Reference Include="System.Net.Http" />
@@ -478,6 +478,7 @@
<Compile Include="PropertyEditors\DecimalValidator.cs" />
<Compile Include="PropertyEditors\ValueConverters\GridValueConverter.cs" />
<Compile Include="PropertyEditors\ValueConverters\DecimalValueConverter.cs" />
<Compile Include="PropertyEditors\ValueConverters\LabelValueConverter.cs" />
<Compile Include="PropertyEditors\ValueConverters\ImageCropperValueConverter.cs" />
<Compile Include="Publishing\UnPublishedStatusType.cs" />
<Compile Include="Publishing\UnPublishStatus.cs" />

View File

@@ -15,5 +15,5 @@
<package id="Owin" version="1.0" targetFramework="net45" />
<package id="semver" version="1.1.2" targetFramework="net45" />
<package id="SharpZipLib" version="0.86.0" targetFramework="net4" />
<package id="SqlServerCE" version="4.0.0.0" targetFramework="net4" />
<package id="SqlServerCE" version="4.0.0.1" targetFramework="net45" />
</packages>

View File

@@ -72,7 +72,7 @@
<system.data>
<DbProviderFactories>
<remove invariant="System.Data.SqlServerCe.4.0" />
<add name="Microsoft SQL Server Compact Data Provider 4.0" invariant="System.Data.SqlServerCe.4.0" description=".NET Framework Data Provider for Microsoft SQL Server Compact" type="System.Data.SqlServerCe.SqlCeProviderFactory, System.Data.SqlServerCe, Version=4.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" />
<add name="Microsoft SQL Server Compact Data Provider 4.0" invariant="System.Data.SqlServerCe.4.0" description=".NET Framework Data Provider for Microsoft SQL Server Compact" type="System.Data.SqlServerCe.SqlCeProviderFactory, System.Data.SqlServerCe, Version=4.0.0.1, Culture=neutral, PublicKeyToken=89845dcd8080cc91" />
<remove invariant="MySql.Data.MySqlClient" />
<add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=6.6.4.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" />
</DbProviderFactories>

View File

@@ -42,7 +42,7 @@ namespace Umbraco.Tests.Cache.DistributedCache
{
for (var i = 1; i < 11; i++)
{
Web.Cache.DistributedCache.Instance.Refresh(Guid.Parse("E0F452CB-DCB2-4E84-B5A5-4F01744C5C73"), i);
global::Umbraco.Web.Cache.DistributedCache.Instance.Refresh(Guid.Parse("E0F452CB-DCB2-4E84-B5A5-4F01744C5C73"), i);
}
Assert.AreEqual(10, ((TestServerMessenger)ServerMessengerResolver.Current.Messenger).IntIdsRefreshed.Count);
}
@@ -52,7 +52,7 @@ namespace Umbraco.Tests.Cache.DistributedCache
{
for (var i = 0; i < 10; i++)
{
Web.Cache.DistributedCache.Instance.Refresh(
global::Umbraco.Web.Cache.DistributedCache.Instance.Refresh(
Guid.Parse("E0F452CB-DCB2-4E84-B5A5-4F01744C5C73"),
x => x.Id,
new TestObjectWithId{Id = i});
@@ -65,7 +65,7 @@ namespace Umbraco.Tests.Cache.DistributedCache
{
for (var i = 0; i < 11; i++)
{
Web.Cache.DistributedCache.Instance.Refresh(Guid.Parse("E0F452CB-DCB2-4E84-B5A5-4F01744C5C73"), Guid.NewGuid());
global::Umbraco.Web.Cache.DistributedCache.Instance.Refresh(Guid.Parse("E0F452CB-DCB2-4E84-B5A5-4F01744C5C73"), Guid.NewGuid());
}
Assert.AreEqual(11, ((TestServerMessenger)ServerMessengerResolver.Current.Messenger).GuidIdsRefreshed.Count);
}
@@ -75,7 +75,7 @@ namespace Umbraco.Tests.Cache.DistributedCache
{
for (var i = 1; i < 13; i++)
{
Web.Cache.DistributedCache.Instance.Remove(Guid.Parse("E0F452CB-DCB2-4E84-B5A5-4F01744C5C73"), i);
global::Umbraco.Web.Cache.DistributedCache.Instance.Remove(Guid.Parse("E0F452CB-DCB2-4E84-B5A5-4F01744C5C73"), i);
}
Assert.AreEqual(12, ((TestServerMessenger)ServerMessengerResolver.Current.Messenger).IntIdsRemoved.Count);
}
@@ -85,7 +85,7 @@ namespace Umbraco.Tests.Cache.DistributedCache
{
for (var i = 0; i < 13; i++)
{
Web.Cache.DistributedCache.Instance.RefreshAll(Guid.Parse("E0F452CB-DCB2-4E84-B5A5-4F01744C5C73"));
global::Umbraco.Web.Cache.DistributedCache.Instance.RefreshAll(Guid.Parse("E0F452CB-DCB2-4E84-B5A5-4F01744C5C73"));
}
Assert.AreEqual(13, ((TestServerMessenger)ServerMessengerResolver.Current.Messenger).CountOfFullRefreshes);
}

View File

@@ -56,19 +56,19 @@ namespace Umbraco.Tests.Integration
ServiceContext.DomainService.Save(new UmbracoDomain("*100112") { DomainName = "*100112", RootContentId = c3.Id, LanguageId = l2.Id });
var content = c2;
var culture = Web.Models.ContentExtensions.GetCulture(null,
var culture = global::Umbraco.Web.Models.ContentExtensions.GetCulture(null,
ServiceContext.DomainService, ServiceContext.LocalizationService, ServiceContext.ContentService,
content.Id, content.Path, new Uri("http://domain1.com/"));
Assert.AreEqual("en-US", culture.Name);
content = c2;
culture = Web.Models.ContentExtensions.GetCulture(null,
culture = global::Umbraco.Web.Models.ContentExtensions.GetCulture(null,
ServiceContext.DomainService, ServiceContext.LocalizationService, ServiceContext.ContentService,
content.Id, content.Path, new Uri("http://domain1.fr/"));
Assert.AreEqual("fr-FR", culture.Name);
content = c4;
culture = Web.Models.ContentExtensions.GetCulture(null,
culture = global::Umbraco.Web.Models.ContentExtensions.GetCulture(null,
ServiceContext.DomainService, ServiceContext.LocalizationService, ServiceContext.ContentService,
content.Id, content.Path, new Uri("http://domain1.fr/"));
Assert.AreEqual("de-DE", culture.Name);
@@ -104,13 +104,13 @@ namespace Umbraco.Tests.Integration
//ServiceContext.DomainService.Save(new UmbracoDomain("*100112") { DomainName = "*100112", RootContentId = c3.Id, LanguageId = l2.Id });
var content = c2;
var culture = Web.Models.ContentExtensions.GetCulture(null,
var culture = Umbraco.Web.Models.ContentExtensions.GetCulture(null,
ServiceContext.DomainService, ServiceContext.LocalizationService, ServiceContext.ContentService,
content.Id, content.Path, new Uri("http://domain1.com/"));
Assert.AreEqual("de-DE", culture.Name);
content = c4;
culture = Web.Models.ContentExtensions.GetCulture(null,
culture = Umbraco.Web.Models.ContentExtensions.GetCulture(null,
ServiceContext.DomainService, ServiceContext.LocalizationService, ServiceContext.ContentService,
content.Id, content.Path, new Uri("http://domain1.fr/"));
Assert.AreEqual("fr-FR", culture.Name);

View File

@@ -1,17 +1,20 @@
using System;
using System.Linq;
using Moq;
using NUnit.Framework;
using Umbraco.Core.Logging;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
using Umbraco.Core.Persistence.Migrations;
using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Tests.TestHelpers;
namespace Umbraco.Tests.Persistence.SyntaxProvider
{
[NUnit.Framework.Ignore("This doesn't actually test anything")]
//[NUnit.Framework.Ignore("This doesn't actually test anything")]
[TestFixture]
public class MySqlSyntaxProviderTests
public class MySqlSyntaxProviderTests : BaseUsingSqlCeSyntax
{
[SetUp]
public void SetUp()
@@ -20,6 +23,7 @@ namespace Umbraco.Tests.Persistence.SyntaxProvider
}
[Test]
[NUnit.Framework.Ignore]
public void Can_Generate_Create_Table_Statement()
{
var type = typeof(TagRelationshipDto);
@@ -48,5 +52,40 @@ namespace Umbraco.Tests.Persistence.SyntaxProvider
{
SqlSyntaxContext.SqlSyntaxProvider = null;
}
[Test]
public void U4_8017()
{
var logger = Mock.Of<ILogger>();
var migration = new TestMigration(SqlSyntaxContext.SqlSyntaxProvider, logger);
var context = new MigrationContext(DatabaseProviders.MySql, null, logger);
migration.Context = context;
migration.Up();
var x = context.Expressions;
Assert.AreEqual(1, x.Count);
var e = x.First().ToString();
// SQLCE provider *does* use UniqueIdentifier
// MySql using GUID...? because InitColumnTypeMap() missing in provider, fixed
Assert.AreEqual("ALTER TABLE `cmsPropertyTypeGroup` ADD COLUMN `uniqueID` char(36) NOT NULL", e);
}
[Migration("1.0.0", 0, "Test")]
private class TestMigration : MigrationBase
{
public TestMigration(ISqlSyntaxProvider sqlSyntax, ILogger logger) : base(sqlSyntax, logger)
{}
public override void Up()
{
Create.Column("uniqueID").OnTable("cmsPropertyTypeGroup").AsGuid().NotNullable().WithDefault(SystemMethods.NewGuid);
}
public override void Down()
{
throw new NotImplementedException();
}
}
}
}

View File

@@ -9,11 +9,12 @@ using Umbraco.Core.Persistence.DatabaseModelDefinitions;
using Umbraco.Core.Persistence.Migrations.Syntax.Create.Index;
using Umbraco.Core.Persistence.Migrations.Syntax.Expressions;
using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Tests.TestHelpers;
namespace Umbraco.Tests.Persistence.SyntaxProvider
{
[TestFixture]
public class SqlCeSyntaxProviderTests
public class SqlCeSyntaxProviderTests : BaseUsingSqlCeSyntax
{
[Test]

View File

@@ -147,7 +147,7 @@ namespace Umbraco.Tests.PropertyEditors
var dataTypeService = new Mock<IDataTypeService>();
dataTypeService.Setup(x => x.GetPreValuesCollectionByDataTypeId(It.IsAny<int>())).Returns(new PreValueCollection(Enumerable.Empty<PreValue>()));
var converter = new Web.PropertyEditors.ValueConverters.ImageCropperValueConverter(dataTypeService.Object);
var converter = new Umbraco.Web.PropertyEditors.ValueConverters.ImageCropperValueConverter(dataTypeService.Object);
var result = converter.ConvertDataToSource(new PublishedPropertyType("test", 0, "test"), val1, false); // does not use type for conversion
var resultShouldMatch = val2.SerializeToCropDataSet();

View File

@@ -234,9 +234,9 @@ namespace Umbraco.Tests.PublishedContent
new PublishedPropertyType("prop1", 1, "?"),
};
var contentType1 = new PublishedContentType(1, "ContentType1", props);
var contentType2 = new PublishedContentType(2, "ContentType2", props);
var contentType2s = new PublishedContentType(3, "ContentType2Sub", props);
var contentType1 = new PublishedContentType(1, "ContentType1", Enumerable.Empty<string>(), props);
var contentType2 = new PublishedContentType(2, "ContentType2", Enumerable.Empty<string>(), props);
var contentType2s = new PublishedContentType(3, "ContentType2Sub", Enumerable.Empty<string>(), props);
cache.Add(new SolidPublishedContent(contentType1)
{

View File

@@ -355,7 +355,11 @@ namespace Umbraco.Tests.PublishedContent
private static readonly PublishedPropertyType Default = new PublishedPropertyType("*", 0, "?");
public AutoPublishedContentType(int id, string alias, IEnumerable<PublishedPropertyType> propertyTypes)
: base(id, alias, propertyTypes)
: base(id, alias, Enumerable.Empty<string>(), propertyTypes)
{ }
public AutoPublishedContentType(int id, string alias, IEnumerable<string> compositionAliases, IEnumerable<PublishedPropertyType> propertyTypes)
: base(id, alias, compositionAliases, propertyTypes)
{ }
public override PublishedPropertyType GetPropertyType(string alias)

View File

@@ -50,7 +50,8 @@ namespace Umbraco.Tests.PublishedContent
new PublishedPropertyType("content", 0, Constants.PropertyEditors.TinyMCEAlias),
new PublishedPropertyType("testRecursive", 0, "?"),
};
var type = new AutoPublishedContentType(0, "anything", propertyTypes);
var compositionAliases = new[] {"MyCompositionAlias"};
var type = new AutoPublishedContentType(0, "anything", compositionAliases, propertyTypes);
PublishedContentType.GetPublishedContentTypeCallback = (alias) => type;
}
@@ -468,6 +469,16 @@ namespace Umbraco.Tests.PublishedContent
Assert.IsNull(doc.FirstChild<IPublishedContent>());
}
[Test]
public void IsComposedOf()
{
var doc = GetNode(1173);
var isComposedOf = doc.IsComposedOf("MyCompositionAlias");
Assert.IsTrue(isComposedOf);
}
[Test]
public void HasProperty()
{
@@ -475,8 +486,7 @@ namespace Umbraco.Tests.PublishedContent
var hasProp = doc.HasProperty(Constants.Conventions.Content.UrlAlias);
Assert.AreEqual(true, (bool)hasProp);
Assert.IsTrue(hasProp);
}
[Test]

View File

@@ -380,7 +380,7 @@ namespace Umbraco.Tests.Routing
var content = umbracoContext.ContentCache.GetById(nodeId);
Assert.IsNotNull(content);
var culture = Web.Models.ContentExtensions.GetCulture(umbracoContext, domainService, ServiceContext.LocalizationService, null, content.Id, content.Path, new Uri(currentUrl));
var culture = global::Umbraco.Web.Models.ContentExtensions.GetCulture(umbracoContext, domainService, ServiceContext.LocalizationService, null, content.Id, content.Path, new Uri(currentUrl));
Assert.AreEqual(expectedCulture, culture.Name);
}
}

View File

@@ -0,0 +1,85 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Web;
using Microsoft.Owin;
using Moq;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Logging;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Profiling;
using Umbraco.Tests.TestHelpers;
using Umbraco.Web;
using Umbraco.Web.Routing;
using Umbraco.Web.Security;
using Umbraco.Web.Security.Identity;
namespace Umbraco.Tests.Security
{
[TestFixture]
public class BackOfficeCookieManagerTests
{
[Test]
public void ShouldAuthenticateRequest_When_Not_Configured()
{
//should force app ctx to show not-configured
ConfigurationManager.AppSettings.Set("umbracoConfigurationStatus", "");
var dbCtx = new Mock<DatabaseContext>(Mock.Of<IDatabaseFactory>(), Mock.Of<ILogger>(), Mock.Of<ISqlSyntaxProvider>(), "test");
dbCtx.Setup(x => x.IsDatabaseConfigured).Returns(false);
var appCtx = new ApplicationContext(
dbCtx.Object,
MockHelper.GetMockedServiceContext(),
CacheHelper.CreateDisabledCacheHelper(),
new ProfilingLogger(Mock.Of<ILogger>(), Mock.Of<IProfiler>()));
var umbCtx = UmbracoContext.CreateContext(
Mock.Of<HttpContextBase>(),
appCtx,
new WebSecurity(Mock.Of<HttpContextBase>(), appCtx),
Mock.Of<IUmbracoSettingsSection>(), new List<IUrlProvider>(), false);
var mgr = new BackOfficeCookieManager(Mock.Of<IUmbracoContextAccessor>(accessor => accessor.Value == umbCtx));
var result = mgr.ShouldAuthenticateRequest(Mock.Of<IOwinContext>(), new Uri("http://localhost/umbraco"));
Assert.IsFalse(result);
}
[Test]
public void ShouldAuthenticateRequest_When_Configured()
{
var dbCtx = new Mock<DatabaseContext>(Mock.Of<IDatabaseFactory>(), Mock.Of<ILogger>(), Mock.Of<ISqlSyntaxProvider>(), "test");
dbCtx.Setup(x => x.IsDatabaseConfigured).Returns(true);
var appCtx = new ApplicationContext(
dbCtx.Object,
MockHelper.GetMockedServiceContext(),
CacheHelper.CreateDisabledCacheHelper(),
new ProfilingLogger(Mock.Of<ILogger>(), Mock.Of<IProfiler>()));
var umbCtx = UmbracoContext.CreateContext(
Mock.Of<HttpContextBase>(),
appCtx,
new WebSecurity(Mock.Of<HttpContextBase>(), appCtx),
Mock.Of<IUmbracoSettingsSection>(), new List<IUrlProvider>(), false);
var mgr = new BackOfficeCookieManager(Mock.Of<IUmbracoContextAccessor>(accessor => accessor.Value == umbCtx));
var request = new Mock<OwinRequest>();
request.Setup(owinRequest => owinRequest.Uri).Returns(new Uri("http://localhost/umbraco"));
var result = mgr.ShouldAuthenticateRequest(
Mock.Of<IOwinContext>(context => context.Request == request.Object),
new Uri("http://localhost/umbraco"));
Assert.IsTrue(result);
}
//TODO : Write remaining tests for `ShouldAuthenticateRequest`
}
}

View File

@@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Text;
@@ -9,6 +8,7 @@ using Newtonsoft.Json;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.Security;
using Umbraco.Core.Services;
namespace Umbraco.Tests.Security
{

View File

@@ -75,6 +75,10 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Lucene.Net.2.9.4.1\lib\net40\Lucene.Net.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Owin, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Web.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Private>True</Private>
<HintPath>..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll</HintPath>
@@ -94,6 +98,10 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\NUnit.2.6.2\lib\nunit.framework.dll</HintPath>
</Reference>
<Reference Include="Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0ebd12fd5e55cc5, processorArchitecture=MSIL">
<HintPath>..\packages\Owin.1.0\lib\net40\Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Semver">
<HintPath>..\packages\semver.1.1.2\lib\net45\Semver.dll</HintPath>
</Reference>
@@ -102,13 +110,13 @@
<Reference Include="System.configuration" />
<Reference Include="System.Core" />
<Reference Include="System.Data.Entity.Design" />
<Reference Include="System.Data.SqlServerCe, Version=4.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<Reference Include="System.Data.SqlServerCe, Version=4.0.0.1, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<Private>True</Private>
<HintPath>..\packages\SqlServerCE.4.0.0.0\lib\System.Data.SqlServerCe.dll</HintPath>
<HintPath>..\packages\SqlServerCE.4.0.0.1\lib\System.Data.SqlServerCe.dll</HintPath>
</Reference>
<Reference Include="System.Data.SqlServerCe.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<Reference Include="System.Data.SqlServerCe.Entity, Version=4.0.0.1, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<Private>True</Private>
<HintPath>..\packages\SqlServerCE.4.0.0.0\lib\System.Data.SqlServerCe.Entity.dll</HintPath>
<HintPath>..\packages\SqlServerCE.4.0.0.1\lib\System.Data.SqlServerCe.Entity.dll</HintPath>
</Reference>
<Reference Include="System.Drawing" />
<Reference Include="System.Net.Http" />
@@ -167,10 +175,10 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="AngularIntegration\AngularAntiForgeryTests.cs" />
<Compile Include="AngularIntegration\ContentModelSerializationTests.cs" />
<Compile Include="AngularIntegration\JsInitializationTests.cs" />
<Compile Include="AngularIntegration\ServerVariablesParserTests.cs" />
<Compile Include="Web\AngularIntegration\AngularAntiForgeryTests.cs" />
<Compile Include="Web\AngularIntegration\ContentModelSerializationTests.cs" />
<Compile Include="Web\AngularIntegration\JsInitializationTests.cs" />
<Compile Include="Web\AngularIntegration\ServerVariablesParserTests.cs" />
<Compile Include="ApplicationContextTests.cs" />
<Compile Include="AttemptTests.cs" />
<Compile Include="Cache\CacheRefresherTests.cs" />
@@ -180,12 +188,12 @@
<Compile Include="Cache\FullDataSetCachePolicyTests.cs" />
<Compile Include="Cache\SingleItemsOnlyCachePolicyTests.cs" />
<Compile Include="Collections\DeepCloneableListTests.cs" />
<Compile Include="Controllers\BackOfficeControllerUnitTests.cs" />
<Compile Include="Web\Controllers\BackOfficeControllerUnitTests.cs" />
<Compile Include="DelegateExtensionsTests.cs" />
<Compile Include="Logging\AsyncRollingFileAppenderTest.cs" />
<Compile Include="Logging\DebugAppender.cs" />
<Compile Include="Logging\ParallelForwarderTest.cs" />
<Compile Include="Mvc\RenderIndexActionSelectorAttributeTests.cs" />
<Compile Include="Web\Mvc\RenderIndexActionSelectorAttributeTests.cs" />
<Compile Include="Persistence\Repositories\AuditRepositoryTest.cs" />
<Compile Include="Persistence\Repositories\DomainRepositoryTest.cs" />
<Compile Include="Persistence\Repositories\PartialViewRepositoryTests.cs" />
@@ -195,6 +203,7 @@
<Compile Include="Resolvers\ResolverBaseTest.cs" />
<Compile Include="Routing\RoutesCacheTests.cs" />
<Compile Include="Routing\UrlRoutingTestBase.cs" />
<Compile Include="Security\BackOfficeCookieManagerTests.cs" />
<Compile Include="Security\UmbracoBackOfficeIdentityTests.cs" />
<Compile Include="Services\ContentTypeServiceExtensionsTests.cs" />
<Compile Include="Services\PublicAccessServiceTests.cs" />
@@ -235,8 +244,8 @@
<Compile Include="Models\UmbracoEntityTests.cs" />
<Compile Include="Models\UserTests.cs" />
<Compile Include="Models\UserTypeTests.cs" />
<Compile Include="Mvc\SurfaceControllerTests.cs" />
<Compile Include="Mvc\UmbracoViewPageTests.cs" />
<Compile Include="Web\Mvc\SurfaceControllerTests.cs" />
<Compile Include="Web\Mvc\UmbracoViewPageTests.cs" />
<Compile Include="BootManagers\CoreBootManagerTests.cs" />
<Compile Include="BootManagers\WebBootManagerTests.cs" />
<Compile Include="Cache\ObjectCacheProviderTests.cs" />
@@ -311,9 +320,9 @@
<Compile Include="Configurations\UmbracoSettings\ViewstateMoverModuleElementTests.cs" />
<Compile Include="Configurations\UmbracoSettings\WebRoutingElementDefaultTests.cs" />
<Compile Include="Configurations\UmbracoSettings\WebRoutingElementTests.cs" />
<Compile Include="Controllers\WebApiEditors\ContentControllerUnitTests.cs" />
<Compile Include="Controllers\WebApiEditors\FilterAllowedOutgoingContentAttributeTests.cs" />
<Compile Include="Controllers\WebApiEditors\MediaControllerUnitTests.cs" />
<Compile Include="Web\Controllers\WebApiEditors\ContentControllerUnitTests.cs" />
<Compile Include="Web\Controllers\WebApiEditors\FilterAllowedOutgoingContentAttributeTests.cs" />
<Compile Include="Web\Controllers\WebApiEditors\MediaControllerUnitTests.cs" />
<Compile Include="CoreXml\FrameworkXmlTests.cs" />
<Compile Include="DynamicsAndReflection\QueryableExtensionTests.cs" />
<Compile Include="DynamicsAndReflection\ExtensionMethodFinderTests.cs" />
@@ -323,8 +332,8 @@
<Compile Include="Migrations\Upgrades\ValidateV7UpgradeTest.cs" />
<Compile Include="Models\ContentExtensionsTests.cs" />
<Compile Include="Models\UserExtensionsTests.cs" />
<Compile Include="Mvc\MergeParentContextViewDataAttributeTests.cs" />
<Compile Include="Mvc\ViewDataDictionaryExtensionTests.cs" />
<Compile Include="Web\Mvc\MergeParentContextViewDataAttributeTests.cs" />
<Compile Include="Web\Mvc\ViewDataDictionaryExtensionTests.cs" />
<Compile Include="Persistence\PetaPocoExtensionsTest.cs" />
<Compile Include="Persistence\Querying\ContentTypeSqlMappingTests.cs" />
<Compile Include="Persistence\Repositories\MacroRepositoryTest.cs" />
@@ -421,7 +430,7 @@
<Compile Include="PublishedContent\PublishedContentTests.cs" />
<Compile Include="PublishedContent\PublishedMediaTests.cs" />
<Compile Include="HashCodeCombinerTests.cs" />
<Compile Include="Mvc\HtmlHelperExtensionMethodsTests.cs" />
<Compile Include="Web\Mvc\HtmlHelperExtensionMethodsTests.cs" />
<Compile Include="IO\IOHelperTest.cs" />
<Compile Include="LibraryTests.cs" />
<Compile Include="PropertyEditors\PropertyEditorValueConverterTests.cs" />
@@ -506,7 +515,7 @@
<DependentUpon>ImportResources.resx</DependentUpon>
</Compile>
<Compile Include="Services\ThreadSafetyServiceTest.cs" />
<Compile Include="Controllers\PluginControllerAreaTests.cs" />
<Compile Include="Web\Controllers\PluginControllerAreaTests.cs" />
<Compile Include="Cache\DistributedCache\DistributedCacheTests.cs" />
<Compile Include="Templates\MasterPageHelperTests.cs" />
<Compile Include="TestHelpers\BaseDatabaseFactoryTest.cs" />
@@ -570,6 +579,7 @@
<Compile Include="Plugins\TypeFinderTests.cs" />
<Compile Include="Routing\UmbracoModuleTests.cs" />
<Compile Include="VersionExtensionTests.cs" />
<Compile Include="Web\WebExtensionMethodTests.cs" />
<Compile Include="XmlExtensionsTests.cs" />
<Compile Include="XmlHelperTests.cs" />
</ItemGroup>
@@ -739,11 +749,16 @@
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>xcopy "$(ProjectDir)"..\packages\SqlServerCE.4.0.0.0\amd64\*.* "$(TargetDir)amd64\" /Y /F /E /D
xcopy "$(ProjectDir)"..\packages\SqlServerCE.4.0.0.0\x86\*.* "$(TargetDir)x86\" /Y /F /E /D</PostBuildEvent>
<PostBuildEvent>
</PostBuildEvent>
</PropertyGroup>
<Import Project="$(SolutionDir)\.nuget\nuget.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
<PropertyGroup>
<PreBuildEvent>xcopy "$(ProjectDir)"..\packages\SqlServerCE.4.0.0.1\amd64\*.* "$(TargetDir)amd64\" /Y /F /E /I /C /D
xcopy "$(ProjectDir)"..\packages\SqlServerCE.4.0.0.1\x86\*.* "$(TargetDir)x86\" /Y /F /E /I /C /D</PreBuildEvent>
</PropertyGroup>
<Import Project="$(SolutionDir)\.nuget\nuget.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>

View File

@@ -1,20 +1,11 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.IO;
using System.Net;
using System.Security.Claims;
using System.Security.Principal;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Web.Security;
using NUnit.Framework;
using Umbraco.Core.Security;
using Umbraco.Tests.TestHelpers;
using Umbraco.Web.WebApi.Filters;
namespace Umbraco.Tests.AngularIntegration
namespace Umbraco.Tests.Web.AngularIntegration
{
[TestFixture]
public class AngularAntiForgeryTests

View File

@@ -1,80 +1,77 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NUnit.Framework;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Umbraco.Core;
using Umbraco.Web.Models.ContentEditing;
namespace Umbraco.Tests.AngularIntegration
{
[TestFixture]
public class ContentModelSerializationTests
{
[Test]
public void Content_Display_To_Json()
{
//create 3 tabs with 3 properties each
var tabs = new List<Tab<ContentPropertyDisplay>>();
for (var tabIndex = 0; tabIndex < 3; tabIndex ++)
{
var props = new List<ContentPropertyDisplay>();
for (var propertyIndex = 0; propertyIndex < 3; propertyIndex ++)
{
props.Add(new ContentPropertyDisplay
{
Alias = "property" + propertyIndex,
Label = "Property " + propertyIndex,
Id = propertyIndex,
Value = "value" + propertyIndex,
Config = new Dictionary<string, object> {{ propertyIndex.ToInvariantString(), "value" }},
Description = "Description " + propertyIndex,
View = "~/Views/View" + propertyIndex,
HideLabel = false
});
}
tabs.Add(new Tab<ContentPropertyDisplay>()
{
Alias = "Tab" + tabIndex,
Label = "Tab" + tabIndex,
Properties = props
});
}
var displayModel = new ContentItemDisplay
{
Id = 1234,
Name = "Test",
Tabs = tabs
};
var json = JsonConvert.SerializeObject(displayModel);
var jObject = JObject.Parse(json);
Assert.AreEqual("1234", jObject["id"].ToString());
Assert.AreEqual("Test", jObject["name"].ToString());
Assert.AreEqual(3, jObject["tabs"].Count());
for (var tab = 0; tab < jObject["tabs"].Count(); tab++)
{
Assert.AreEqual("Tab" + tab, jObject["tabs"][tab]["alias"].ToString());
Assert.AreEqual("Tab" + tab, jObject["tabs"][tab]["label"].ToString());
Assert.AreEqual(3, jObject["tabs"][tab]["properties"].Count());
for (var prop = 0; prop < jObject["tabs"][tab]["properties"].Count(); prop++)
{
Assert.AreEqual("property" + prop, jObject["tabs"][tab]["properties"][prop]["alias"].ToString());
Assert.AreEqual("Property " + prop, jObject["tabs"][tab]["properties"][prop]["label"].ToString());
Assert.AreEqual(prop, jObject["tabs"][tab]["properties"][prop]["id"].Value<int>());
Assert.AreEqual("value" + prop, jObject["tabs"][tab]["properties"][prop]["value"].ToString());
Assert.AreEqual("{\"" + prop + "\":\"value\"}", jObject["tabs"][tab]["properties"][prop]["config"].ToString(Formatting.None));
Assert.AreEqual("Description " + prop, jObject["tabs"][tab]["properties"][prop]["description"].ToString());
Assert.AreEqual(false, jObject["tabs"][tab]["properties"][prop]["hideLabel"].Value<bool>());
}
}
}
}
}
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Web.Models.ContentEditing;
namespace Umbraco.Tests.Web.AngularIntegration
{
[TestFixture]
public class ContentModelSerializationTests
{
[Test]
public void Content_Display_To_Json()
{
//create 3 tabs with 3 properties each
var tabs = new List<Tab<ContentPropertyDisplay>>();
for (var tabIndex = 0; tabIndex < 3; tabIndex ++)
{
var props = new List<ContentPropertyDisplay>();
for (var propertyIndex = 0; propertyIndex < 3; propertyIndex ++)
{
props.Add(new ContentPropertyDisplay
{
Alias = "property" + propertyIndex,
Label = "Property " + propertyIndex,
Id = propertyIndex,
Value = "value" + propertyIndex,
Config = new Dictionary<string, object> {{ propertyIndex.ToInvariantString(), "value" }},
Description = "Description " + propertyIndex,
View = "~/Views/View" + propertyIndex,
HideLabel = false
});
}
tabs.Add(new Tab<ContentPropertyDisplay>()
{
Alias = "Tab" + tabIndex,
Label = "Tab" + tabIndex,
Properties = props
});
}
var displayModel = new ContentItemDisplay
{
Id = 1234,
Name = "Test",
Tabs = tabs
};
var json = JsonConvert.SerializeObject(displayModel);
var jObject = JObject.Parse(json);
Assert.AreEqual("1234", jObject["id"].ToString());
Assert.AreEqual("Test", jObject["name"].ToString());
Assert.AreEqual(3, jObject["tabs"].Count());
for (var tab = 0; tab < jObject["tabs"].Count(); tab++)
{
Assert.AreEqual("Tab" + tab, jObject["tabs"][tab]["alias"].ToString());
Assert.AreEqual("Tab" + tab, jObject["tabs"][tab]["label"].ToString());
Assert.AreEqual(3, jObject["tabs"][tab]["properties"].Count());
for (var prop = 0; prop < jObject["tabs"][tab]["properties"].Count(); prop++)
{
Assert.AreEqual("property" + prop, jObject["tabs"][tab]["properties"][prop]["alias"].ToString());
Assert.AreEqual("Property " + prop, jObject["tabs"][tab]["properties"][prop]["label"].ToString());
Assert.AreEqual(prop, jObject["tabs"][tab]["properties"][prop]["id"].Value<int>());
Assert.AreEqual("value" + prop, jObject["tabs"][tab]["properties"][prop]["value"].ToString());
Assert.AreEqual("{\"" + prop + "\":\"value\"}", jObject["tabs"][tab]["properties"][prop]["config"].ToString(Formatting.None));
Assert.AreEqual("Description " + prop, jObject["tabs"][tab]["properties"][prop]["description"].ToString());
Assert.AreEqual(false, jObject["tabs"][tab]["properties"][prop]["hideLabel"].Value<bool>());
}
}
}
}
}

View File

@@ -1,41 +1,36 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NUnit.Framework;
using Newtonsoft.Json.Linq;
using Umbraco.Core.Manifest;
using Umbraco.Web.UI.JavaScript;
namespace Umbraco.Tests.AngularIntegration
{
[TestFixture]
public class JsInitializationTests
{
[Test]
public void Get_Default_Init()
{
var init = JsInitialization.GetDefaultInitialization();
Assert.IsTrue(init.Any());
}
[Test]
public void Parse_Main()
{
var result = JsInitialization.ParseMain(new[] {"[World]", "Hello" });
Assert.AreEqual(@"LazyLoad.js([World], function () {
//we need to set the legacy UmbClientMgr path
UmbClientMgr.setUmbracoPath('Hello');
jQuery(document).ready(function () {
angular.bootstrap(document, ['umbraco']);
});
});", result);
}
}
}
using System.Linq;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Web.UI.JavaScript;
namespace Umbraco.Tests.Web.AngularIntegration
{
[TestFixture]
public class JsInitializationTests
{
[Test]
public void Get_Default_Init()
{
var init = JsInitialization.GetDefaultInitialization();
Assert.IsTrue(init.Any());
}
[Test]
public void Parse_Main()
{
var result = JsInitialization.ParseMain(new[] {"[World]", "Hello" });
Assert.AreEqual(@"LazyLoad.js([World], function () {
//we need to set the legacy UmbClientMgr path
UmbClientMgr.setUmbracoPath('Hello');
jQuery(document).ready(function () {
angular.bootstrap(document, ['umbraco']);
});
});".StripWhitespace(), result.StripWhitespace());
}
}
}

View File

@@ -1,33 +1,34 @@
using System.Collections.Generic;
using NUnit.Framework;
using Umbraco.Web.UI.JavaScript;
namespace Umbraco.Tests.AngularIntegration
{
[TestFixture]
public class ServerVariablesParserTests
{
[Test]
public void Parse()
{
var d = new Dictionary<string, object>();
d.Add("test1", "Test 1");
d.Add("test2", "Test 2");
d.Add("test3", "Test 3");
d.Add("test4", "Test 4");
d.Add("test5", "Test 5");
var output = ServerVariablesParser.Parse(d);
Assert.IsTrue(output.Contains(@"Umbraco.Sys.ServerVariables = {
""test1"": ""Test 1"",
""test2"": ""Test 2"",
""test3"": ""Test 3"",
""test4"": ""Test 4"",
""test5"": ""Test 5""
} ;"));
}
}
using System.Collections.Generic;
using NUnit.Framework;
using Umbraco.Web.UI.JavaScript;
using Umbraco.Core;
namespace Umbraco.Tests.Web.AngularIntegration
{
[TestFixture]
public class ServerVariablesParserTests
{
[Test]
public void Parse()
{
var d = new Dictionary<string, object>();
d.Add("test1", "Test 1");
d.Add("test2", "Test 2");
d.Add("test3", "Test 3");
d.Add("test4", "Test 4");
d.Add("test5", "Test 5");
var output = ServerVariablesParser.Parse(d).StripWhitespace();
Assert.IsTrue(output.Contains(@"Umbraco.Sys.ServerVariables = {
""test1"": ""Test 1"",
""test2"": ""Test 2"",
""test3"": ""Test 3"",
""test4"": ""Test 4"",
""test5"": ""Test 5""
} ;".StripWhitespace()));
}
}
}

View File

@@ -2,7 +2,7 @@
using NUnit.Framework;
using Umbraco.Web.Editors;
namespace Umbraco.Tests.Controllers
namespace Umbraco.Tests.Web.Controllers
{
[TestFixture]
public class BackOfficeControllerUnitTests

View File

@@ -4,7 +4,7 @@ using Umbraco.Tests.TestHelpers;
using Umbraco.Web;
using Umbraco.Web.Mvc;
namespace Umbraco.Tests.Controllers
namespace Umbraco.Tests.Web.Controllers
{
[TestFixture]
public class PluginControllerAreaTests : BaseWebTest

View File

@@ -1,366 +1,366 @@
using System.Collections.Generic;
using System.Web.Http;
using Moq;
using NUnit.Framework;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Membership;
using Umbraco.Core.Services;
using Umbraco.Web.Editors;
namespace Umbraco.Tests.Controllers.WebApiEditors
{
[TestFixture]
public class ContentControllerUnitTests
{
[Test]
public void Access_Allowed_By_Path()
{
//arrange
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(9);
userMock.Setup(u => u.StartContentId).Returns(-1);
var user = userMock.Object;
var contentMock = new Mock<IContent>();
contentMock.Setup(c => c.Path).Returns("-1,1234,5678");
var content = contentMock.Object;
var contentServiceMock = new Mock<IContentService>();
contentServiceMock.Setup(x => x.GetById(1234)).Returns(content);
var contentService = contentServiceMock.Object;
//act
var result = ContentController.CheckPermissions(new Dictionary<string, object>(), user, null, contentService, 1234);
//assert
Assert.IsTrue(result);
}
[Test]
public void Throws_Exception_When_No_Content_Found()
{
//arrange
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(9);
userMock.Setup(u => u.StartContentId).Returns(-1);
var user = userMock.Object;
var contentMock = new Mock<IContent>();
contentMock.Setup(c => c.Path).Returns("-1,1234,5678");
var content = contentMock.Object;
var contentServiceMock = new Mock<IContentService>();
contentServiceMock.Setup(x => x.GetById(0)).Returns(content);
var contentService = contentServiceMock.Object;
var userServiceMock = new Mock<IUserService>();
var permissions = new List<EntityPermission>();
userServiceMock.Setup(x => x.GetPermissions(user, 1234)).Returns(permissions);
var userService = userServiceMock.Object;
//act/assert
Assert.Throws<HttpResponseException>(() => ContentController.CheckPermissions(new Dictionary<string, object>(), user, userService, contentService, 1234, new[] { 'F' }));
}
[Test]
public void No_Access_By_Path()
{
//arrange
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(9);
userMock.Setup(u => u.StartContentId).Returns(9876);
var user = userMock.Object;
var contentMock = new Mock<IContent>();
contentMock.Setup(c => c.Path).Returns("-1,1234,5678");
var content = contentMock.Object;
var contentServiceMock = new Mock<IContentService>();
contentServiceMock.Setup(x => x.GetById(1234)).Returns(content);
var contentService = contentServiceMock.Object;
var userServiceMock = new Mock<IUserService>();
var permissions = new List<EntityPermission>();
userServiceMock.Setup(x => x.GetPermissions(user, 1234)).Returns(permissions);
var userService = userServiceMock.Object;
//act
var result = ContentController.CheckPermissions(new Dictionary<string, object>(), user, userService, contentService, 1234, new[] { 'F'});
//assert
Assert.IsFalse(result);
}
[Test]
public void No_Access_By_Permission()
{
//arrange
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(9);
userMock.Setup(u => u.StartContentId).Returns(-1);
var user = userMock.Object;
var contentMock = new Mock<IContent>();
contentMock.Setup(c => c.Path).Returns("-1,1234,5678");
var content = contentMock.Object;
var contentServiceMock = new Mock<IContentService>();
contentServiceMock.Setup(x => x.GetById(1234)).Returns(content);
var contentService = contentServiceMock.Object;
var userServiceMock = new Mock<IUserService>();
var permissions = new List<EntityPermission>
{
new EntityPermission(9, 1234, new string[]{ "A", "B", "C" })
};
userServiceMock.Setup(x => x.GetPermissions(user, 1234)).Returns(permissions);
var userService = userServiceMock.Object;
//act
var result = ContentController.CheckPermissions(new Dictionary<string, object>(), user, userService, contentService, 1234, new[] { 'F'});
//assert
Assert.IsFalse(result);
}
[Test]
public void Access_Allowed_By_Permission()
{
//arrange
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(9);
userMock.Setup(u => u.StartContentId).Returns(-1);
var user = userMock.Object;
var contentMock = new Mock<IContent>();
contentMock.Setup(c => c.Path).Returns("-1,1234,5678");
var content = contentMock.Object;
var contentServiceMock = new Mock<IContentService>();
contentServiceMock.Setup(x => x.GetById(1234)).Returns(content);
var contentService = contentServiceMock.Object;
var userServiceMock = new Mock<IUserService>();
var permissions = new List<EntityPermission>
{
new EntityPermission(9, 1234, new string[]{ "A", "F", "C" })
};
userServiceMock.Setup(x => x.GetPermissions(user, 1234)).Returns(permissions);
var userService = userServiceMock.Object;
//act
var result = ContentController.CheckPermissions(new Dictionary<string, object>(), user, userService, contentService, 1234, new[] { 'F'});
//assert
Assert.IsTrue(result);
}
[Test]
public void Access_To_Root_By_Path()
{
//arrange
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(0);
userMock.Setup(u => u.StartContentId).Returns(-1);
var user = userMock.Object;
//act
var result = ContentController.CheckPermissions(new Dictionary<string, object>(), user, null, null, -1);
//assert
Assert.IsTrue(result);
}
[Test]
public void Access_To_Recycle_Bin_By_Path()
{
//arrange
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(0);
userMock.Setup(u => u.StartContentId).Returns(-1);
var user = userMock.Object;
//act
var result = ContentController.CheckPermissions(new Dictionary<string, object>(), user, null, null, -20);
//assert
Assert.IsTrue(result);
}
[Test]
public void No_Access_To_Recycle_Bin_By_Path()
{
//arrange
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(0);
userMock.Setup(u => u.StartContentId).Returns(1234);
var user = userMock.Object;
//act
var result = ContentController.CheckPermissions(new Dictionary<string, object>(), user, null, null, -20);
//assert
Assert.IsFalse(result);
}
[Test]
public void No_Access_To_Root_By_Path()
{
//arrange
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(0);
userMock.Setup(u => u.StartContentId).Returns(1234);
var user = userMock.Object;
//act
var result = ContentController.CheckPermissions(new Dictionary<string, object>(), user, null, null, -1);
//assert
Assert.IsFalse(result);
}
[Test]
public void Access_To_Root_By_Permission()
{
//arrange
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(0);
userMock.Setup(u => u.StartContentId).Returns(-1);
var user = userMock.Object;
var userServiceMock = new Mock<IUserService>();
var permissions = new List<EntityPermission>
{
new EntityPermission(9, 1234, new string[]{ "A" })
};
userServiceMock.Setup(x => x.GetPermissions(user, -1)).Returns(permissions);
var userService = userServiceMock.Object;
//act
var result = ContentController.CheckPermissions(new Dictionary<string, object>(), user, userService, null, -1, new[] { 'A'});
//assert
Assert.IsTrue(result);
}
[Test]
public void No_Access_To_Root_By_Permission()
{
//arrange
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(0);
userMock.Setup(u => u.StartContentId).Returns(-1);
var user = userMock.Object;
var userServiceMock = new Mock<IUserService>();
var permissions = new List<EntityPermission>
{
new EntityPermission(9, 1234, new string[]{ "A" })
};
userServiceMock.Setup(x => x.GetPermissions(user, -1)).Returns(permissions);
var userService = userServiceMock.Object;
//act
var result = ContentController.CheckPermissions(new Dictionary<string, object>(), user, userService, null, -1, new[] { 'B'});
//assert
Assert.IsFalse(result);
}
[Test]
public void Access_To_Recycle_Bin_By_Permission()
{
//arrange
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(0);
userMock.Setup(u => u.StartContentId).Returns(-1);
var user = userMock.Object;
var userServiceMock = new Mock<IUserService>();
var permissions = new List<EntityPermission>
{
new EntityPermission(9, 1234, new string[]{ "A" })
};
userServiceMock.Setup(x => x.GetPermissions(user, -20)).Returns(permissions);
var userService = userServiceMock.Object;
//act
var result = ContentController.CheckPermissions(new Dictionary<string, object>(), user, userService, null, -20, new[] { 'A'});
//assert
Assert.IsTrue(result);
}
[Test]
public void No_Access_To_Recycle_Bin_By_Permission()
{
//arrange
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(0);
userMock.Setup(u => u.StartContentId).Returns(-1);
var user = userMock.Object;
var userServiceMock = new Mock<IUserService>();
var permissions = new List<EntityPermission>
{
new EntityPermission(9, 1234, new string[]{ "A" })
};
userServiceMock.Setup(x => x.GetPermissions(user, -20)).Returns(permissions);
var userService = userServiceMock.Object;
//act
var result = ContentController.CheckPermissions(new Dictionary<string, object>(), user, userService, null, -20, new[] { 'B'});
//assert
Assert.IsFalse(result);
}
}
//NOTE: The below self hosted stuff does work so need to get some tests written. Some are not possible atm because
// of the legacy SQL calls like checking permissions.
//[TestFixture]
//public class ContentControllerHostedTests : BaseRoutingTest
//{
// protected override DatabaseBehavior DatabaseTestBehavior
// {
// get { return DatabaseBehavior.NoDatabasePerFixture; }
// }
// public override void TearDown()
// {
// base.TearDown();
// UmbracoAuthorizeAttribute.Enable = true;
// UmbracoApplicationAuthorizeAttribute.Enable = true;
// }
// /// <summary>
// /// Tests to ensure that the response filter works so that any items the user
// /// doesn't have access to are removed
// /// </summary>
// [Test]
// public async void Get_By_Ids_Response_Filtered()
// {
// UmbracoAuthorizeAttribute.Enable = false;
// UmbracoApplicationAuthorizeAttribute.Enable = false;
// var baseUrl = string.Format("http://{0}:9876", Environment.MachineName);
// var url = baseUrl + "/api/Content/GetByIds?ids=1&ids=2";
// var routingCtx = GetRoutingContext(url, 1234, null, true);
// var config = new HttpSelfHostConfiguration(baseUrl);
// using (var server = new HttpSelfHostServer(config))
// {
// var route = config.Routes.MapHttpRoute("test", "api/Content/GetByIds",
// new
// {
// controller = "Content",
// action = "GetByIds",
// id = RouteParameter.Optional
// });
// route.DataTokens["Namespaces"] = new string[] { "Umbraco.Web.Editors" };
// var client = new HttpClient(server);
// var request = new HttpRequestMessage
// {
// RequestUri = new Uri(url),
// Method = HttpMethod.Get
// };
// var result = await client.SendAsync(request);
// }
// }
//}
}
using System.Collections.Generic;
using System.Web.Http;
using Moq;
using NUnit.Framework;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Membership;
using Umbraco.Core.Services;
using Umbraco.Web.Editors;
namespace Umbraco.Tests.Web.Controllers.WebApiEditors
{
[TestFixture]
public class ContentControllerUnitTests
{
[Test]
public void Access_Allowed_By_Path()
{
//arrange
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(9);
userMock.Setup(u => u.StartContentId).Returns(-1);
var user = userMock.Object;
var contentMock = new Mock<IContent>();
contentMock.Setup(c => c.Path).Returns("-1,1234,5678");
var content = contentMock.Object;
var contentServiceMock = new Mock<IContentService>();
contentServiceMock.Setup(x => x.GetById(1234)).Returns(content);
var contentService = contentServiceMock.Object;
//act
var result = ContentController.CheckPermissions(new Dictionary<string, object>(), user, null, contentService, 1234);
//assert
Assert.IsTrue(result);
}
[Test]
public void Throws_Exception_When_No_Content_Found()
{
//arrange
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(9);
userMock.Setup(u => u.StartContentId).Returns(-1);
var user = userMock.Object;
var contentMock = new Mock<IContent>();
contentMock.Setup(c => c.Path).Returns("-1,1234,5678");
var content = contentMock.Object;
var contentServiceMock = new Mock<IContentService>();
contentServiceMock.Setup(x => x.GetById(0)).Returns(content);
var contentService = contentServiceMock.Object;
var userServiceMock = new Mock<IUserService>();
var permissions = new List<EntityPermission>();
userServiceMock.Setup(x => x.GetPermissions(user, 1234)).Returns(permissions);
var userService = userServiceMock.Object;
//act/assert
Assert.Throws<HttpResponseException>(() => ContentController.CheckPermissions(new Dictionary<string, object>(), user, userService, contentService, 1234, new[] { 'F' }));
}
[Test]
public void No_Access_By_Path()
{
//arrange
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(9);
userMock.Setup(u => u.StartContentId).Returns(9876);
var user = userMock.Object;
var contentMock = new Mock<IContent>();
contentMock.Setup(c => c.Path).Returns("-1,1234,5678");
var content = contentMock.Object;
var contentServiceMock = new Mock<IContentService>();
contentServiceMock.Setup(x => x.GetById(1234)).Returns(content);
var contentService = contentServiceMock.Object;
var userServiceMock = new Mock<IUserService>();
var permissions = new List<EntityPermission>();
userServiceMock.Setup(x => x.GetPermissions(user, 1234)).Returns(permissions);
var userService = userServiceMock.Object;
//act
var result = ContentController.CheckPermissions(new Dictionary<string, object>(), user, userService, contentService, 1234, new[] { 'F'});
//assert
Assert.IsFalse(result);
}
[Test]
public void No_Access_By_Permission()
{
//arrange
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(9);
userMock.Setup(u => u.StartContentId).Returns(-1);
var user = userMock.Object;
var contentMock = new Mock<IContent>();
contentMock.Setup(c => c.Path).Returns("-1,1234,5678");
var content = contentMock.Object;
var contentServiceMock = new Mock<IContentService>();
contentServiceMock.Setup(x => x.GetById(1234)).Returns(content);
var contentService = contentServiceMock.Object;
var userServiceMock = new Mock<IUserService>();
var permissions = new List<EntityPermission>
{
new EntityPermission(9, 1234, new string[]{ "A", "B", "C" })
};
userServiceMock.Setup(x => x.GetPermissions(user, 1234)).Returns(permissions);
var userService = userServiceMock.Object;
//act
var result = ContentController.CheckPermissions(new Dictionary<string, object>(), user, userService, contentService, 1234, new[] { 'F'});
//assert
Assert.IsFalse(result);
}
[Test]
public void Access_Allowed_By_Permission()
{
//arrange
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(9);
userMock.Setup(u => u.StartContentId).Returns(-1);
var user = userMock.Object;
var contentMock = new Mock<IContent>();
contentMock.Setup(c => c.Path).Returns("-1,1234,5678");
var content = contentMock.Object;
var contentServiceMock = new Mock<IContentService>();
contentServiceMock.Setup(x => x.GetById(1234)).Returns(content);
var contentService = contentServiceMock.Object;
var userServiceMock = new Mock<IUserService>();
var permissions = new List<EntityPermission>
{
new EntityPermission(9, 1234, new string[]{ "A", "F", "C" })
};
userServiceMock.Setup(x => x.GetPermissions(user, 1234)).Returns(permissions);
var userService = userServiceMock.Object;
//act
var result = ContentController.CheckPermissions(new Dictionary<string, object>(), user, userService, contentService, 1234, new[] { 'F'});
//assert
Assert.IsTrue(result);
}
[Test]
public void Access_To_Root_By_Path()
{
//arrange
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(0);
userMock.Setup(u => u.StartContentId).Returns(-1);
var user = userMock.Object;
//act
var result = ContentController.CheckPermissions(new Dictionary<string, object>(), user, null, null, -1);
//assert
Assert.IsTrue(result);
}
[Test]
public void Access_To_Recycle_Bin_By_Path()
{
//arrange
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(0);
userMock.Setup(u => u.StartContentId).Returns(-1);
var user = userMock.Object;
//act
var result = ContentController.CheckPermissions(new Dictionary<string, object>(), user, null, null, -20);
//assert
Assert.IsTrue(result);
}
[Test]
public void No_Access_To_Recycle_Bin_By_Path()
{
//arrange
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(0);
userMock.Setup(u => u.StartContentId).Returns(1234);
var user = userMock.Object;
//act
var result = ContentController.CheckPermissions(new Dictionary<string, object>(), user, null, null, -20);
//assert
Assert.IsFalse(result);
}
[Test]
public void No_Access_To_Root_By_Path()
{
//arrange
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(0);
userMock.Setup(u => u.StartContentId).Returns(1234);
var user = userMock.Object;
//act
var result = ContentController.CheckPermissions(new Dictionary<string, object>(), user, null, null, -1);
//assert
Assert.IsFalse(result);
}
[Test]
public void Access_To_Root_By_Permission()
{
//arrange
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(0);
userMock.Setup(u => u.StartContentId).Returns(-1);
var user = userMock.Object;
var userServiceMock = new Mock<IUserService>();
var permissions = new List<EntityPermission>
{
new EntityPermission(9, 1234, new string[]{ "A" })
};
userServiceMock.Setup(x => x.GetPermissions(user, -1)).Returns(permissions);
var userService = userServiceMock.Object;
//act
var result = ContentController.CheckPermissions(new Dictionary<string, object>(), user, userService, null, -1, new[] { 'A'});
//assert
Assert.IsTrue(result);
}
[Test]
public void No_Access_To_Root_By_Permission()
{
//arrange
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(0);
userMock.Setup(u => u.StartContentId).Returns(-1);
var user = userMock.Object;
var userServiceMock = new Mock<IUserService>();
var permissions = new List<EntityPermission>
{
new EntityPermission(9, 1234, new string[]{ "A" })
};
userServiceMock.Setup(x => x.GetPermissions(user, -1)).Returns(permissions);
var userService = userServiceMock.Object;
//act
var result = ContentController.CheckPermissions(new Dictionary<string, object>(), user, userService, null, -1, new[] { 'B'});
//assert
Assert.IsFalse(result);
}
[Test]
public void Access_To_Recycle_Bin_By_Permission()
{
//arrange
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(0);
userMock.Setup(u => u.StartContentId).Returns(-1);
var user = userMock.Object;
var userServiceMock = new Mock<IUserService>();
var permissions = new List<EntityPermission>
{
new EntityPermission(9, 1234, new string[]{ "A" })
};
userServiceMock.Setup(x => x.GetPermissions(user, -20)).Returns(permissions);
var userService = userServiceMock.Object;
//act
var result = ContentController.CheckPermissions(new Dictionary<string, object>(), user, userService, null, -20, new[] { 'A'});
//assert
Assert.IsTrue(result);
}
[Test]
public void No_Access_To_Recycle_Bin_By_Permission()
{
//arrange
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(0);
userMock.Setup(u => u.StartContentId).Returns(-1);
var user = userMock.Object;
var userServiceMock = new Mock<IUserService>();
var permissions = new List<EntityPermission>
{
new EntityPermission(9, 1234, new string[]{ "A" })
};
userServiceMock.Setup(x => x.GetPermissions(user, -20)).Returns(permissions);
var userService = userServiceMock.Object;
//act
var result = ContentController.CheckPermissions(new Dictionary<string, object>(), user, userService, null, -20, new[] { 'B'});
//assert
Assert.IsFalse(result);
}
}
//NOTE: The below self hosted stuff does work so need to get some tests written. Some are not possible atm because
// of the legacy SQL calls like checking permissions.
//[TestFixture]
//public class ContentControllerHostedTests : BaseRoutingTest
//{
// protected override DatabaseBehavior DatabaseTestBehavior
// {
// get { return DatabaseBehavior.NoDatabasePerFixture; }
// }
// public override void TearDown()
// {
// base.TearDown();
// UmbracoAuthorizeAttribute.Enable = true;
// UmbracoApplicationAuthorizeAttribute.Enable = true;
// }
// /// <summary>
// /// Tests to ensure that the response filter works so that any items the user
// /// doesn't have access to are removed
// /// </summary>
// [Test]
// public async void Get_By_Ids_Response_Filtered()
// {
// UmbracoAuthorizeAttribute.Enable = false;
// UmbracoApplicationAuthorizeAttribute.Enable = false;
// var baseUrl = string.Format("http://{0}:9876", Environment.MachineName);
// var url = baseUrl + "/api/Content/GetByIds?ids=1&ids=2";
// var routingCtx = GetRoutingContext(url, 1234, null, true);
// var config = new HttpSelfHostConfiguration(baseUrl);
// using (var server = new HttpSelfHostServer(config))
// {
// var route = config.Routes.MapHttpRoute("test", "api/Content/GetByIds",
// new
// {
// controller = "Content",
// action = "GetByIds",
// id = RouteParameter.Optional
// });
// route.DataTokens["Namespaces"] = new string[] { "Umbraco.Web.Editors" };
// var client = new HttpClient(server);
// var request = new HttpRequestMessage
// {
// RequestUri = new Uri(url),
// Method = HttpMethod.Get
// };
// var result = await client.SendAsync(request);
// }
// }
//}
}

View File

@@ -1,136 +1,136 @@
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Net.Http.Headers;
using Moq;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.Models.Membership;
using Umbraco.Core.Services;
using Umbraco.Web.Models.ContentEditing;
using Umbraco.Web.WebApi.Filters;
namespace Umbraco.Tests.Controllers.WebApiEditors
{
[TestFixture]
public class FilterAllowedOutgoingContentAttributeTests
{
[Test]
public void GetValueFromResponse_Already_EnumerableContent()
{
var att = new FilterAllowedOutgoingContentAttribute(typeof(IEnumerable<ContentItemBasic>));
var val = new List<ContentItemBasic>() {new ContentItemBasic()};
var result = att.GetValueFromResponse(
new ObjectContent(typeof (IEnumerable<ContentItemBasic>),
val,
new JsonMediaTypeFormatter(),
new MediaTypeHeaderValue("html/text")));
Assert.AreEqual(val, result);
Assert.AreEqual(1, ((IEnumerable<ContentItemBasic>)result).Count());
}
[Test]
public void GetValueFromResponse_From_Property()
{
var att = new FilterAllowedOutgoingContentAttribute(typeof(IEnumerable<ContentItemBasic>), "MyList");
var val = new List<ContentItemBasic>() { new ContentItemBasic() };
var container = new MyTestClass() {MyList = val};
var result = att.GetValueFromResponse(
new ObjectContent(typeof(MyTestClass),
container,
new JsonMediaTypeFormatter(),
new MediaTypeHeaderValue("html/text")));
Assert.AreEqual(val, result);
Assert.AreEqual(1, ((IEnumerable<ContentItemBasic>)result).Count());
}
[Test]
public void GetValueFromResponse_Returns_Null_Not_Found_Property()
{
var att = new FilterAllowedOutgoingContentAttribute(typeof(IEnumerable<ContentItemBasic>), "DontFind");
var val = new List<ContentItemBasic>() { new ContentItemBasic() };
var container = new MyTestClass() { MyList = val };
var result = att.GetValueFromResponse(
new ObjectContent(typeof(MyTestClass),
container,
new JsonMediaTypeFormatter(),
new MediaTypeHeaderValue("html/text")));
Assert.AreEqual(null, result);
}
[Test]
public void Filter_On_Start_Node()
{
var att = new FilterAllowedOutgoingContentAttribute(typeof(IEnumerable<ContentItemBasic>));
var list = new List<dynamic>();
var path = "";
for (var i = 0; i < 10; i++)
{
if (i > 0 && path.EndsWith(",") == false)
{
path += ",";
}
path += i.ToInvariantString();
list.Add(new ContentItemBasic { Id = i, Name = "Test" + i, ParentId = i, Path = path });
}
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(9);
userMock.Setup(u => u.StartContentId).Returns(5);
var user = userMock.Object;
att.FilterBasedOnStartNode(list, user);
Assert.AreEqual(5, list.Count);
}
[Test]
public void Filter_On_Permissions()
{
var att = new FilterAllowedOutgoingContentAttribute(typeof(IEnumerable<ContentItemBasic>));
var list = new List<dynamic>();
for (var i = 0; i < 10; i++)
{
list.Add(new ContentItemBasic{Id = i, Name = "Test" + i, ParentId = -1});
}
var ids = list.Select(x => (int)x.Id).ToArray();
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(9);
userMock.Setup(u => u.StartContentId).Returns(-1);
var user = userMock.Object;
var userServiceMock = new Mock<IUserService>();
//we're only assigning 3 nodes browse permissions so that is what we expect as a result
var permissions = new List<EntityPermission>
{
new EntityPermission(9, 1, new string[]{ "F" }),
new EntityPermission(9, 2, new string[]{ "F" }),
new EntityPermission(9, 3, new string[]{ "F" }),
new EntityPermission(9, 4, new string[]{ "A" })
};
userServiceMock.Setup(x => x.GetPermissions(user, ids)).Returns(permissions);
var userService = userServiceMock.Object;
att.FilterBasedOnPermissions(list, user, userService);
Assert.AreEqual(3, list.Count);
Assert.AreEqual(1, list.ElementAt(0).Id);
Assert.AreEqual(2, list.ElementAt(1).Id);
Assert.AreEqual(3, list.ElementAt(2).Id);
}
private class MyTestClass
{
public IEnumerable<ContentItemBasic> MyList { get; set; }
}
}
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Net.Http.Headers;
using Moq;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.Models.Membership;
using Umbraco.Core.Services;
using Umbraco.Web.Models.ContentEditing;
using Umbraco.Web.WebApi.Filters;
namespace Umbraco.Tests.Web.Controllers.WebApiEditors
{
[TestFixture]
public class FilterAllowedOutgoingContentAttributeTests
{
[Test]
public void GetValueFromResponse_Already_EnumerableContent()
{
var att = new FilterAllowedOutgoingContentAttribute(typeof(IEnumerable<ContentItemBasic>));
var val = new List<ContentItemBasic>() {new ContentItemBasic()};
var result = att.GetValueFromResponse(
new ObjectContent(typeof (IEnumerable<ContentItemBasic>),
val,
new JsonMediaTypeFormatter(),
new MediaTypeHeaderValue("html/text")));
Assert.AreEqual(val, result);
Assert.AreEqual(1, ((IEnumerable<ContentItemBasic>)result).Count());
}
[Test]
public void GetValueFromResponse_From_Property()
{
var att = new FilterAllowedOutgoingContentAttribute(typeof(IEnumerable<ContentItemBasic>), "MyList");
var val = new List<ContentItemBasic>() { new ContentItemBasic() };
var container = new MyTestClass() {MyList = val};
var result = att.GetValueFromResponse(
new ObjectContent(typeof(MyTestClass),
container,
new JsonMediaTypeFormatter(),
new MediaTypeHeaderValue("html/text")));
Assert.AreEqual(val, result);
Assert.AreEqual(1, ((IEnumerable<ContentItemBasic>)result).Count());
}
[Test]
public void GetValueFromResponse_Returns_Null_Not_Found_Property()
{
var att = new FilterAllowedOutgoingContentAttribute(typeof(IEnumerable<ContentItemBasic>), "DontFind");
var val = new List<ContentItemBasic>() { new ContentItemBasic() };
var container = new MyTestClass() { MyList = val };
var result = att.GetValueFromResponse(
new ObjectContent(typeof(MyTestClass),
container,
new JsonMediaTypeFormatter(),
new MediaTypeHeaderValue("html/text")));
Assert.AreEqual(null, result);
}
[Test]
public void Filter_On_Start_Node()
{
var att = new FilterAllowedOutgoingContentAttribute(typeof(IEnumerable<ContentItemBasic>));
var list = new List<dynamic>();
var path = "";
for (var i = 0; i < 10; i++)
{
if (i > 0 && path.EndsWith(",") == false)
{
path += ",";
}
path += i.ToInvariantString();
list.Add(new ContentItemBasic { Id = i, Name = "Test" + i, ParentId = i, Path = path });
}
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(9);
userMock.Setup(u => u.StartContentId).Returns(5);
var user = userMock.Object;
att.FilterBasedOnStartNode(list, user);
Assert.AreEqual(5, list.Count);
}
[Test]
public void Filter_On_Permissions()
{
var att = new FilterAllowedOutgoingContentAttribute(typeof(IEnumerable<ContentItemBasic>));
var list = new List<dynamic>();
for (var i = 0; i < 10; i++)
{
list.Add(new ContentItemBasic{Id = i, Name = "Test" + i, ParentId = -1});
}
var ids = list.Select(x => (int)x.Id).ToArray();
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(9);
userMock.Setup(u => u.StartContentId).Returns(-1);
var user = userMock.Object;
var userServiceMock = new Mock<IUserService>();
//we're only assigning 3 nodes browse permissions so that is what we expect as a result
var permissions = new List<EntityPermission>
{
new EntityPermission(9, 1, new string[]{ "F" }),
new EntityPermission(9, 2, new string[]{ "F" }),
new EntityPermission(9, 3, new string[]{ "F" }),
new EntityPermission(9, 4, new string[]{ "A" })
};
userServiceMock.Setup(x => x.GetPermissions(user, ids)).Returns(permissions);
var userService = userServiceMock.Object;
att.FilterBasedOnPermissions(list, user, userService);
Assert.AreEqual(3, list.Count);
Assert.AreEqual(1, list.ElementAt(0).Id);
Assert.AreEqual(2, list.ElementAt(1).Id);
Assert.AreEqual(3, list.ElementAt(2).Id);
}
private class MyTestClass
{
public IEnumerable<ContentItemBasic> MyList { get; set; }
}
}
}

View File

@@ -1,142 +1,142 @@
using System.Collections.Generic;
using System.Web.Http;
using Moq;
using NUnit.Framework;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Membership;
using Umbraco.Core.Services;
using Umbraco.Web.Editors;
namespace Umbraco.Tests.Controllers.WebApiEditors
{
[TestFixture]
public class MediaControllerUnitTests
{
[Test]
public void Access_Allowed_By_Path()
{
//arrange
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(9);
userMock.Setup(u => u.StartMediaId).Returns(-1);
var user = userMock.Object;
var mediaMock = new Mock<IMedia>();
mediaMock.Setup(m => m.Path).Returns("-1,1234,5678");
var media = mediaMock.Object;
var mediaServiceMock = new Mock<IMediaService>();
mediaServiceMock.Setup(x => x.GetById(1234)).Returns(media);
var mediaService = mediaServiceMock.Object;
//act
var result = MediaController.CheckPermissions(new Dictionary<string, object>(), user, mediaService, 1234);
//assert
Assert.IsTrue(result);
}
[Test]
public void Throws_Exception_When_No_Media_Found()
{
//arrange
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(9);
userMock.Setup(u => u.StartMediaId).Returns(-1);
var user = userMock.Object;
var mediaMock = new Mock<IMedia>();
mediaMock.Setup(m => m.Path).Returns("-1,1234,5678");
var media = mediaMock.Object;
var mediaServiceMock = new Mock<IMediaService>();
mediaServiceMock.Setup(x => x.GetById(0)).Returns(media);
var mediaService = mediaServiceMock.Object;
//act/assert
Assert.Throws<HttpResponseException>(() => MediaController.CheckPermissions(new Dictionary<string, object>(), user, mediaService, 1234));
}
[Test]
public void No_Access_By_Path()
{
//arrange
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(9);
userMock.Setup(u => u.StartMediaId).Returns(9876);
var user = userMock.Object;
var mediaMock = new Mock<IMedia>();
mediaMock.Setup(m => m.Path).Returns("-1,1234,5678");
var media = mediaMock.Object;
var mediaServiceMock = new Mock<IMediaService>();
mediaServiceMock.Setup(x => x.GetById(1234)).Returns(media);
var mediaService = mediaServiceMock.Object;
//act
var result = MediaController.CheckPermissions(new Dictionary<string, object>(), user, mediaService, 1234);
//assert
Assert.IsFalse(result);
}
[Test]
public void Access_To_Root_By_Path()
{
//arrange
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(0);
userMock.Setup(u => u.StartMediaId).Returns(-1);
var user = userMock.Object;
//act
var result = MediaController.CheckPermissions(new Dictionary<string, object>(), user, null, -1);
//assert
Assert.IsTrue(result);
}
[Test]
public void No_Access_To_Root_By_Path()
{
//arrange
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(0);
userMock.Setup(u => u.StartMediaId).Returns(1234);
var user = userMock.Object;
//act
var result = MediaController.CheckPermissions(new Dictionary<string, object>(), user, null, -1);
//assert
Assert.IsFalse(result);
}
[Test]
public void Access_To_Recycle_Bin_By_Path()
{
//arrange
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(0);
userMock.Setup(u => u.StartMediaId).Returns(-1);
var user = userMock.Object;
//act
var result = MediaController.CheckPermissions(new Dictionary<string, object>(), user, null, -21);
//assert
Assert.IsTrue(result);
}
[Test]
public void No_Access_To_Recycle_Bin_By_Path()
{
//arrange
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(0);
userMock.Setup(u => u.StartMediaId).Returns(1234);
var user = userMock.Object;
//act
var result = MediaController.CheckPermissions(new Dictionary<string, object>(), user, null, -21);
//assert
Assert.IsFalse(result);
}
}
using System.Collections.Generic;
using System.Web.Http;
using Moq;
using NUnit.Framework;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Membership;
using Umbraco.Core.Services;
using Umbraco.Web.Editors;
namespace Umbraco.Tests.Web.Controllers.WebApiEditors
{
[TestFixture]
public class MediaControllerUnitTests
{
[Test]
public void Access_Allowed_By_Path()
{
//arrange
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(9);
userMock.Setup(u => u.StartMediaId).Returns(-1);
var user = userMock.Object;
var mediaMock = new Mock<IMedia>();
mediaMock.Setup(m => m.Path).Returns("-1,1234,5678");
var media = mediaMock.Object;
var mediaServiceMock = new Mock<IMediaService>();
mediaServiceMock.Setup(x => x.GetById(1234)).Returns(media);
var mediaService = mediaServiceMock.Object;
//act
var result = MediaController.CheckPermissions(new Dictionary<string, object>(), user, mediaService, 1234);
//assert
Assert.IsTrue(result);
}
[Test]
public void Throws_Exception_When_No_Media_Found()
{
//arrange
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(9);
userMock.Setup(u => u.StartMediaId).Returns(-1);
var user = userMock.Object;
var mediaMock = new Mock<IMedia>();
mediaMock.Setup(m => m.Path).Returns("-1,1234,5678");
var media = mediaMock.Object;
var mediaServiceMock = new Mock<IMediaService>();
mediaServiceMock.Setup(x => x.GetById(0)).Returns(media);
var mediaService = mediaServiceMock.Object;
//act/assert
Assert.Throws<HttpResponseException>(() => MediaController.CheckPermissions(new Dictionary<string, object>(), user, mediaService, 1234));
}
[Test]
public void No_Access_By_Path()
{
//arrange
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(9);
userMock.Setup(u => u.StartMediaId).Returns(9876);
var user = userMock.Object;
var mediaMock = new Mock<IMedia>();
mediaMock.Setup(m => m.Path).Returns("-1,1234,5678");
var media = mediaMock.Object;
var mediaServiceMock = new Mock<IMediaService>();
mediaServiceMock.Setup(x => x.GetById(1234)).Returns(media);
var mediaService = mediaServiceMock.Object;
//act
var result = MediaController.CheckPermissions(new Dictionary<string, object>(), user, mediaService, 1234);
//assert
Assert.IsFalse(result);
}
[Test]
public void Access_To_Root_By_Path()
{
//arrange
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(0);
userMock.Setup(u => u.StartMediaId).Returns(-1);
var user = userMock.Object;
//act
var result = MediaController.CheckPermissions(new Dictionary<string, object>(), user, null, -1);
//assert
Assert.IsTrue(result);
}
[Test]
public void No_Access_To_Root_By_Path()
{
//arrange
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(0);
userMock.Setup(u => u.StartMediaId).Returns(1234);
var user = userMock.Object;
//act
var result = MediaController.CheckPermissions(new Dictionary<string, object>(), user, null, -1);
//assert
Assert.IsFalse(result);
}
[Test]
public void Access_To_Recycle_Bin_By_Path()
{
//arrange
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(0);
userMock.Setup(u => u.StartMediaId).Returns(-1);
var user = userMock.Object;
//act
var result = MediaController.CheckPermissions(new Dictionary<string, object>(), user, null, -21);
//assert
Assert.IsTrue(result);
}
[Test]
public void No_Access_To_Recycle_Bin_By_Path()
{
//arrange
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(0);
userMock.Setup(u => u.StartMediaId).Returns(1234);
var user = userMock.Object;
//act
var result = MediaController.CheckPermissions(new Dictionary<string, object>(), user, null, -21);
//assert
Assert.IsFalse(result);
}
}
}

View File

@@ -2,7 +2,7 @@ using System.Web.Mvc;
using NUnit.Framework;
using Umbraco.Web;
namespace Umbraco.Tests.Mvc
namespace Umbraco.Tests.Web.Mvc
{
[TestFixture]
public class HtmlHelperExtensionMethodsTests

View File

@@ -1,86 +1,86 @@
using System.Web.Mvc;
using System.Web.Routing;
using NUnit.Framework;
using Umbraco.Tests.TestHelpers;
using Umbraco.Web.Mvc;
namespace Umbraco.Tests.Mvc
{
[TestFixture]
public class MergeParentContextViewDataAttributeTests
{
[Test]
public void Ensure_All_Ancestor_ViewData_Is_Merged()
{
var http = new FakeHttpContextFactory("http://localhost");
//setup an heirarchy
var rootViewCtx = new ViewContext {Controller = new MyController(), RequestContext = http.RequestContext, ViewData = new ViewDataDictionary()};
var parentViewCtx = new ViewContext { Controller = new MyController(), RequestContext = http.RequestContext, RouteData = new RouteData(), ViewData = new ViewDataDictionary() };
parentViewCtx.RouteData.DataTokens.Add("ParentActionViewContext", rootViewCtx);
var controllerCtx = new ControllerContext(http.RequestContext, new MyController()) {RouteData = new RouteData()};
controllerCtx.RouteData.DataTokens.Add("ParentActionViewContext", parentViewCtx);
//set up the view data
controllerCtx.Controller.ViewData["Test1"] = "Test1";
controllerCtx.Controller.ViewData["Test2"] = "Test2";
controllerCtx.Controller.ViewData["Test3"] = "Test3";
parentViewCtx.ViewData["Test4"] = "Test4";
parentViewCtx.ViewData["Test5"] = "Test5";
parentViewCtx.ViewData["Test6"] = "Test6";
rootViewCtx.ViewData["Test7"] = "Test7";
rootViewCtx.ViewData["Test8"] = "Test8";
rootViewCtx.ViewData["Test9"] = "Test9";
var filter = new ResultExecutingContext(controllerCtx, new ContentResult()) {RouteData = controllerCtx.RouteData};
var att = new MergeParentContextViewDataAttribute();
Assert.IsTrue(filter.IsChildAction);
att.OnResultExecuting(filter);
Assert.AreEqual(9, controllerCtx.Controller.ViewData.Count);
}
[Test]
public void Ensure_All_Ancestor_ViewData_Is_Merged_Without_Data_Loss()
{
var http = new FakeHttpContextFactory("http://localhost");
//setup an heirarchy
var rootViewCtx = new ViewContext { Controller = new MyController(), RequestContext = http.RequestContext, ViewData = new ViewDataDictionary() };
var parentViewCtx = new ViewContext { Controller = new MyController(), RequestContext = http.RequestContext, RouteData = new RouteData(), ViewData = new ViewDataDictionary() };
parentViewCtx.RouteData.DataTokens.Add("ParentActionViewContext", rootViewCtx);
var controllerCtx = new ControllerContext(http.RequestContext, new MyController()) { RouteData = new RouteData() };
controllerCtx.RouteData.DataTokens.Add("ParentActionViewContext", parentViewCtx);
//set up the view data with overlapping keys
controllerCtx.Controller.ViewData["Test1"] = "Test1";
controllerCtx.Controller.ViewData["Test2"] = "Test2";
controllerCtx.Controller.ViewData["Test3"] = "Test3";
parentViewCtx.ViewData["Test2"] = "Test4";
parentViewCtx.ViewData["Test3"] = "Test5";
parentViewCtx.ViewData["Test4"] = "Test6";
rootViewCtx.ViewData["Test3"] = "Test7";
rootViewCtx.ViewData["Test4"] = "Test8";
rootViewCtx.ViewData["Test5"] = "Test9";
var filter = new ResultExecutingContext(controllerCtx, new ContentResult()) { RouteData = controllerCtx.RouteData };
var att = new MergeParentContextViewDataAttribute();
Assert.IsTrue(filter.IsChildAction);
att.OnResultExecuting(filter);
Assert.AreEqual(5, controllerCtx.Controller.ViewData.Count);
Assert.AreEqual("Test1", controllerCtx.Controller.ViewData["Test1"]);
Assert.AreEqual("Test2", controllerCtx.Controller.ViewData["Test2"]);
Assert.AreEqual("Test3", controllerCtx.Controller.ViewData["Test3"]);
Assert.AreEqual("Test6", controllerCtx.Controller.ViewData["Test4"]);
Assert.AreEqual("Test9", controllerCtx.Controller.ViewData["Test5"]);
}
internal class MyController : Controller
{
}
}
using System.Web.Mvc;
using System.Web.Routing;
using NUnit.Framework;
using Umbraco.Tests.TestHelpers;
using Umbraco.Web.Mvc;
namespace Umbraco.Tests.Web.Mvc
{
[TestFixture]
public class MergeParentContextViewDataAttributeTests
{
[Test]
public void Ensure_All_Ancestor_ViewData_Is_Merged()
{
var http = new FakeHttpContextFactory("http://localhost");
//setup an heirarchy
var rootViewCtx = new ViewContext {Controller = new MyController(), RequestContext = http.RequestContext, ViewData = new ViewDataDictionary()};
var parentViewCtx = new ViewContext { Controller = new MyController(), RequestContext = http.RequestContext, RouteData = new RouteData(), ViewData = new ViewDataDictionary() };
parentViewCtx.RouteData.DataTokens.Add("ParentActionViewContext", rootViewCtx);
var controllerCtx = new ControllerContext(http.RequestContext, new MyController()) {RouteData = new RouteData()};
controllerCtx.RouteData.DataTokens.Add("ParentActionViewContext", parentViewCtx);
//set up the view data
controllerCtx.Controller.ViewData["Test1"] = "Test1";
controllerCtx.Controller.ViewData["Test2"] = "Test2";
controllerCtx.Controller.ViewData["Test3"] = "Test3";
parentViewCtx.ViewData["Test4"] = "Test4";
parentViewCtx.ViewData["Test5"] = "Test5";
parentViewCtx.ViewData["Test6"] = "Test6";
rootViewCtx.ViewData["Test7"] = "Test7";
rootViewCtx.ViewData["Test8"] = "Test8";
rootViewCtx.ViewData["Test9"] = "Test9";
var filter = new ResultExecutingContext(controllerCtx, new ContentResult()) {RouteData = controllerCtx.RouteData};
var att = new MergeParentContextViewDataAttribute();
Assert.IsTrue(filter.IsChildAction);
att.OnResultExecuting(filter);
Assert.AreEqual(9, controllerCtx.Controller.ViewData.Count);
}
[Test]
public void Ensure_All_Ancestor_ViewData_Is_Merged_Without_Data_Loss()
{
var http = new FakeHttpContextFactory("http://localhost");
//setup an heirarchy
var rootViewCtx = new ViewContext { Controller = new MyController(), RequestContext = http.RequestContext, ViewData = new ViewDataDictionary() };
var parentViewCtx = new ViewContext { Controller = new MyController(), RequestContext = http.RequestContext, RouteData = new RouteData(), ViewData = new ViewDataDictionary() };
parentViewCtx.RouteData.DataTokens.Add("ParentActionViewContext", rootViewCtx);
var controllerCtx = new ControllerContext(http.RequestContext, new MyController()) { RouteData = new RouteData() };
controllerCtx.RouteData.DataTokens.Add("ParentActionViewContext", parentViewCtx);
//set up the view data with overlapping keys
controllerCtx.Controller.ViewData["Test1"] = "Test1";
controllerCtx.Controller.ViewData["Test2"] = "Test2";
controllerCtx.Controller.ViewData["Test3"] = "Test3";
parentViewCtx.ViewData["Test2"] = "Test4";
parentViewCtx.ViewData["Test3"] = "Test5";
parentViewCtx.ViewData["Test4"] = "Test6";
rootViewCtx.ViewData["Test3"] = "Test7";
rootViewCtx.ViewData["Test4"] = "Test8";
rootViewCtx.ViewData["Test5"] = "Test9";
var filter = new ResultExecutingContext(controllerCtx, new ContentResult()) { RouteData = controllerCtx.RouteData };
var att = new MergeParentContextViewDataAttribute();
Assert.IsTrue(filter.IsChildAction);
att.OnResultExecuting(filter);
Assert.AreEqual(5, controllerCtx.Controller.ViewData.Count);
Assert.AreEqual("Test1", controllerCtx.Controller.ViewData["Test1"]);
Assert.AreEqual("Test2", controllerCtx.Controller.ViewData["Test2"]);
Assert.AreEqual("Test3", controllerCtx.Controller.ViewData["Test3"]);
Assert.AreEqual("Test6", controllerCtx.Controller.ViewData["Test4"]);
Assert.AreEqual("Test9", controllerCtx.Controller.ViewData["Test5"]);
}
internal class MyController : Controller
{
}
}
}

View File

@@ -17,7 +17,7 @@ using Umbraco.Web.Mvc;
using Umbraco.Web.Routing;
using Umbraco.Web.Security;
namespace Umbraco.Tests.Mvc
namespace Umbraco.Tests.Web.Mvc
{
[TestFixture]
public class RenderIndexActionSelectorAttributeTests

View File

@@ -1,5 +1,4 @@
using System;
using System.CodeDom;
using System.Linq;
using System.Web;
using System.Web.Mvc;
@@ -12,7 +11,6 @@ using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Dictionary;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.ObjectResolution;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Profiling;
@@ -20,11 +18,10 @@ using Umbraco.Core.Services;
using Umbraco.Tests.TestHelpers;
using Umbraco.Web;
using Umbraco.Web.Mvc;
using Umbraco.Web.PublishedCache;
using Umbraco.Web.Routing;
using Umbraco.Web.Security;
namespace Umbraco.Tests.Mvc
namespace Umbraco.Tests.Web.Mvc
{
[TestFixture]
public class SurfaceControllerTests
@@ -165,7 +162,7 @@ namespace Umbraco.Tests.Mvc
};
var routeData = new RouteData();
routeData.DataTokens.Add("umbraco-route-def", routeDefinition);
routeData.DataTokens.Add(Umbraco.Core.Constants.Web.UmbracoRouteDefinitionDataToken, routeDefinition);
var ctrl = new TestSurfaceController(umbCtx, new UmbracoHelper());
ctrl.ControllerContext = new ControllerContext(contextBase, routeData, ctrl);

View File

@@ -1,27 +1,22 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.Web.Routing;
using System.Xml;
using Moq;
using NUnit.Framework;
using umbraco.BusinessLogic;
using Umbraco.Core;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Events;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Persistence.UnitOfWork;
using Umbraco.Core.Profiling;
using Umbraco.Core.Services;
using Umbraco.Web.Security;
using umbraco.BusinessLogic;
using Umbraco.Core;
using Umbraco.Core.Events;
using Umbraco.Core.Models;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Tests.PublishedContent;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.TestHelpers.Stubs;
using Umbraco.Web;
@@ -30,8 +25,9 @@ using Umbraco.Web.Mvc;
using Umbraco.Web.PublishedCache;
using Umbraco.Web.PublishedCache.XmlPublishedCache;
using Umbraco.Web.Routing;
using Umbraco.Web.Security;
namespace Umbraco.Tests.Mvc
namespace Umbraco.Tests.Web.Mvc
{
[TestFixture]
public class UmbracoViewPageTests
@@ -445,7 +441,7 @@ namespace Umbraco.Tests.Mvc
var context = new ViewContext();
context.RouteData = new RouteData();
context.RouteData.DataTokens.Add("umbraco-context", umbracoContext);
context.RouteData.DataTokens.Add(Umbraco.Core.Constants.Web.UmbracoContextDataToken, umbracoContext);
return context;
}

View File

@@ -1,42 +1,40 @@
using System.Collections.Generic;
using System.Text;
using System.Web.Mvc;
using NUnit.Framework;
using Umbraco.Web.Mvc;
namespace Umbraco.Tests.Mvc
{
[TestFixture]
public class ViewDataDictionaryExtensionTests
{
[Test]
public void Merge_View_Data()
{
var source = new ViewDataDictionary();
var dest = new ViewDataDictionary();
source.Add("Test1", "Test1");
dest.Add("Test2", "Test2");
dest.MergeViewDataFrom(source);
Assert.AreEqual(2, dest.Count);
}
[Test]
public void Merge_View_Data_Retains_Destination_Values()
{
var source = new ViewDataDictionary();
var dest = new ViewDataDictionary();
source.Add("Test1", "Test1");
dest.Add("Test1", "MyValue");
dest.Add("Test2", "Test2");
dest.MergeViewDataFrom(source);
Assert.AreEqual(2, dest.Count);
Assert.AreEqual("MyValue", dest["Test1"]);
Assert.AreEqual("Test2", dest["Test2"]);
}
}
}
using System.Web.Mvc;
using NUnit.Framework;
using Umbraco.Web.Mvc;
namespace Umbraco.Tests.Web.Mvc
{
[TestFixture]
public class ViewDataDictionaryExtensionTests
{
[Test]
public void Merge_View_Data()
{
var source = new ViewDataDictionary();
var dest = new ViewDataDictionary();
source.Add("Test1", "Test1");
dest.Add("Test2", "Test2");
dest.MergeViewDataFrom(source);
Assert.AreEqual(2, dest.Count);
}
[Test]
public void Merge_View_Data_Retains_Destination_Values()
{
var source = new ViewDataDictionary();
var dest = new ViewDataDictionary();
source.Add("Test1", "Test1");
dest.Add("Test1", "MyValue");
dest.Add("Test2", "Test2");
dest.MergeViewDataFrom(source);
Assert.AreEqual(2, dest.Count);
Assert.AreEqual("MyValue", dest["Test1"]);
Assert.AreEqual("Test2", dest["Test2"]);
}
}
}

View File

@@ -0,0 +1,170 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using Moq;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Logging;
using Umbraco.Core.Profiling;
using Umbraco.Web;
using Umbraco.Web.Mvc;
using Umbraco.Web.Routing;
using Umbraco.Web.Security;
namespace Umbraco.Tests.Web
{
[TestFixture]
public class WebExtensionMethodTests
{
[Test]
public void UmbracoContextExtensions_GetUmbracoContext()
{
var appCtx = new ApplicationContext(
CacheHelper.CreateDisabledCacheHelper(),
new ProfilingLogger(Mock.Of<ILogger>(), Mock.Of<IProfiler>()));
var umbCtx = UmbracoContext.CreateContext(
Mock.Of<HttpContextBase>(),
appCtx,
new WebSecurity(Mock.Of<HttpContextBase>(), appCtx),
Mock.Of<IUmbracoSettingsSection>(),
new List<IUrlProvider>(),
false);
var items = new Dictionary<object, object>()
{
{UmbracoContext.HttpContextItemName, umbCtx}
};
var http = new Mock<HttpContextBase>();
http.Setup(x => x.Items).Returns(items);
var result = http.Object.GetUmbracoContext();
Assert.IsNotNull(result);
Assert.AreSame(umbCtx, result);
}
[Test]
public void RouteDataExtensions_GetUmbracoContext()
{
var appCtx = new ApplicationContext(
CacheHelper.CreateDisabledCacheHelper(),
new ProfilingLogger(Mock.Of<ILogger>(), Mock.Of<IProfiler>()));
var umbCtx = UmbracoContext.CreateContext(
Mock.Of<HttpContextBase>(),
appCtx,
new WebSecurity(Mock.Of<HttpContextBase>(), appCtx),
Mock.Of<IUmbracoSettingsSection>(),
new List<IUrlProvider>(),
false);
var r1 = new RouteData();
r1.DataTokens.Add(Core.Constants.Web.UmbracoContextDataToken, umbCtx);
var result = r1.GetUmbracoContext();
Assert.IsNotNull(result);
Assert.AreSame(umbCtx, result);
}
[Test]
public void ControllerContextExtensions_GetUmbracoContext_From_RouteValues()
{
var appCtx = new ApplicationContext(
CacheHelper.CreateDisabledCacheHelper(),
new ProfilingLogger(Mock.Of<ILogger>(), Mock.Of<IProfiler>()));
var umbCtx = UmbracoContext.CreateContext(
Mock.Of<HttpContextBase>(),
appCtx,
new WebSecurity(Mock.Of<HttpContextBase>(), appCtx),
Mock.Of<IUmbracoSettingsSection>(),
new List<IUrlProvider>(),
false);
var r1 = new RouteData();
r1.DataTokens.Add(Core.Constants.Web.UmbracoContextDataToken, umbCtx);
var ctx1 = CreateViewContext(new ControllerContext(Mock.Of<HttpContextBase>(), r1, new MyController()));
var r2 = new RouteData();
r2.DataTokens.Add("ParentActionViewContext", ctx1);
var ctx2 = CreateViewContext(new ControllerContext(Mock.Of<HttpContextBase>(), r2, new MyController()));
var r3 = new RouteData();
r3.DataTokens.Add("ParentActionViewContext", ctx2);
var ctx3 = CreateViewContext(new ControllerContext(Mock.Of<HttpContextBase>(), r3, new MyController()));
var result = ctx3.GetUmbracoContext();
Assert.IsNotNull(result);
Assert.AreSame(umbCtx, result);
}
[Test]
public void ControllerContextExtensions_GetUmbracoContext_From_HttpContext()
{
var appCtx = new ApplicationContext(
CacheHelper.CreateDisabledCacheHelper(),
new ProfilingLogger(Mock.Of<ILogger>(), Mock.Of<IProfiler>()));
var umbCtx = UmbracoContext.CreateContext(
Mock.Of<HttpContextBase>(),
appCtx,
new WebSecurity(Mock.Of<HttpContextBase>(), appCtx),
Mock.Of<IUmbracoSettingsSection>(),
new List<IUrlProvider>(),
false);
var items = new Dictionary<object, object>()
{
{UmbracoContext.HttpContextItemName, umbCtx}
};
var http = new Mock<HttpContextBase>();
http.Setup(x => x.Items).Returns(items);
var r1 = new RouteData();
var ctx1 = CreateViewContext(new ControllerContext(http.Object, r1, new MyController()));
var r2 = new RouteData();
r2.DataTokens.Add("ParentActionViewContext", ctx1);
var ctx2 = CreateViewContext(new ControllerContext(http.Object, r2, new MyController()));
var r3 = new RouteData();
r3.DataTokens.Add("ParentActionViewContext", ctx2);
var ctx3 = CreateViewContext(new ControllerContext(http.Object, r3, new MyController()));
var result = ctx3.GetUmbracoContext();
Assert.IsNotNull(result);
Assert.AreSame(umbCtx, result);
}
[Test]
public void ControllerContextExtensions_GetDataTokenInViewContextHierarchy()
{
var r1 = new RouteData();
r1.DataTokens.Add("hello", "world");
var ctx1 = CreateViewContext(new ControllerContext(Mock.Of<HttpContextBase>(), r1, new MyController()));
var r2 = new RouteData();
r2.DataTokens.Add("ParentActionViewContext", ctx1);
var ctx2 = CreateViewContext(new ControllerContext(Mock.Of<HttpContextBase>(), r2, new MyController()));
var r3 = new RouteData();
r3.DataTokens.Add("ParentActionViewContext", ctx2);
var ctx3 = CreateViewContext(new ControllerContext(Mock.Of<HttpContextBase>(), r3, new MyController()));
var result = ctx3.GetDataTokenInViewContextHierarchy("hello");
Assert.IsNotNull(result as string);
Assert.AreEqual((string)result, "world");
}
private ViewContext CreateViewContext(ControllerContext ctx)
{
return new ViewContext(ctx, Mock.Of<IView>(),
new ViewDataDictionary(), new TempDataDictionary(), new StringWriter());
}
private class MyController : Controller
{
}
}
}

View File

@@ -13,13 +13,15 @@
<package id="Microsoft.AspNet.WebApi.SelfHost" version="4.0.30506.0" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.WebHost" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebPages" version="3.2.3" targetFramework="net45" />
<package id="Microsoft.Owin" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net45" />
<package id="MiniProfiler" version="2.1.0" targetFramework="net45" />
<package id="Moq" version="4.1.1309.0919" targetFramework="net45" />
<package id="Newtonsoft.Json" version="6.0.8" targetFramework="net45" />
<package id="NUnit" version="2.6.2" targetFramework="net45" />
<package id="Owin" version="1.0" targetFramework="net45" />
<package id="Selenium.WebDriver" version="2.32.0" targetFramework="net45" />
<package id="semver" version="1.1.2" targetFramework="net45" />
<package id="SharpZipLib" version="0.86.0" targetFramework="net45" />
<package id="SqlServerCE" version="4.0.0.0" targetFramework="net45" />
<package id="SqlServerCE" version="4.0.0.1" targetFramework="net45" />
</packages>

View File

@@ -361,6 +361,12 @@ Umbraco.Sys.registerNamespace("Umbraco.Application");
rootScope : function(){
return getRootScope();
},
reloadLocation: function() {
var injector = getRootInjector();
var $route = injector.get("$route");
$route.reload();
},
closeModalWindow: function(rVal) {

View File

@@ -14,7 +14,8 @@ angular.module("umbraco.directives")
templateUrl: 'views/components/imaging/umb-image-gravity.html',
scope: {
src: '=',
center: "="
center: "=",
onImageLoaded: "="
},
link: function(scope, element, attrs) {
@@ -26,6 +27,8 @@ angular.module("umbraco.directives")
top: 0
};
scope.loaded = false;
//elements
var $viewport = element.find(".viewport");
var $image = element.find("img");
@@ -42,6 +45,19 @@ angular.module("umbraco.directives")
};
};
scope.setFocalPoint = function(event) {
scope.$emit("imageFocalPointStart");
var offsetX = event.offsetX - 10;
var offsetY = event.offsetY - 10;
calculateGravity(offsetX, offsetY);
lazyEndEvent();
};
var setDimensions = function(){
scope.dimensions.width = $image.width();
scope.dimensions.height = $image.height();
@@ -54,9 +70,9 @@ angular.module("umbraco.directives")
}
};
var calculateGravity = function(){
scope.dimensions.left = $overlay[0].offsetLeft;
scope.dimensions.top = $overlay[0].offsetTop;
var calculateGravity = function(offsetX, offsetY){
scope.dimensions.left = offsetX;
scope.dimensions.top = offsetY;
scope.center.left = (scope.dimensions.left+10) / scope.dimensions.width;
scope.center.top = (scope.dimensions.top+10) / scope.dimensions.height;
@@ -80,7 +96,9 @@ angular.module("umbraco.directives")
},
stop: function() {
scope.$apply(function(){
calculateGravity();
var offsetX = $overlay[0].offsetLeft;
var offsetY = $overlay[0].offsetTop;
calculateGravity(offsetX, offsetY);
});
lazyEndEvent();
@@ -91,8 +109,26 @@ angular.module("umbraco.directives")
$image.load(function(){
$timeout(function(){
setDimensions();
scope.loaded = true;
scope.onImageLoaded();
});
});
$(window).on('resize.umbImageGravity', function(){
scope.$apply(function(){
$timeout(function(){
setDimensions();
});
var offsetX = $overlay[0].offsetLeft;
var offsetY = $overlay[0].offsetTop;
calculateGravity(offsetX, offsetY);
});
});
scope.$on('$destroy', function() {
$(window).off('.umbImageGravity');
});
}
};
});

View File

@@ -26,6 +26,7 @@ angular.module("umbraco.directives")
link: function(scope, element, attrs) {
//// INIT /////
var $image = element.find("img");
scope.loaded = false;
$image.load(function(){
$timeout(function(){
@@ -52,6 +53,7 @@ angular.module("umbraco.directives")
}
setPreviewStyle();
scope.loaded = true;
});
});

View File

@@ -55,7 +55,7 @@ function contentEditingHelper(fileManager, $q, $location, $routeParams, notifica
var deferred = $q.defer();
if (!args.scope.busy && formHelper.submitForm({ scope: args.scope, statusMessage: args.statusMessage })) {
if (!args.scope.busy && formHelper.submitForm({ scope: args.scope, statusMessage: args.statusMessage, action: args.action })) {
args.scope.busy = true;

View File

@@ -50,7 +50,7 @@ function formHelper(angularHelper, serverValidationManager, $timeout, notificati
}
//the first thing any form must do is broadcast the formSubmitting event
args.scope.$broadcast("formSubmitting", { scope: args.scope });
args.scope.$broadcast("formSubmitting", { scope: args.scope, action: args.action });
//then check if the form is valid
if (!args.skipValidation) {

View File

@@ -107,6 +107,7 @@
@import "components/umb-grid.less";
@import "components/umb-empty-state.less";
@import "components/umb-property-editor.less";
@import "components/umb-iconpicker.less";
@import "components/buttons/umb-button.less";
@import "components/buttons/umb-button-group.less";

View File

@@ -0,0 +1,46 @@
.umb-iconpicker {
display: flex;
flex-direction: row;
flex-wrap: wrap;
margin: 0;
}
.umb-iconpicker-item {
display: flex;
flex-direction: row;
flex: 0 0 14.28%;
justify-content: center;
align-items: center;
margin-bottom: 0;
overflow: hidden;
}
.umb-iconpicker-item a {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
padding: 15px 0;
text-decoration: none;
}
.umb-iconpicker-item a:hover,
.umb-iconpicker-item a:focus{
background: darken(@grayLighter, 1%);
outline: none;
}
.umb-iconpicker-item a:active {
background: darken(@grayLighter, 4%);
}
.umb-iconpicker-item i {
font-size: 30px;
}

View File

@@ -16,8 +16,23 @@
.umb-keyboard-shortcuts-overview__overlay-close {
position: absolute;
top: 10px;
right: 10px;
top: 20px;
right: 20px;
font-size: 25px;
border-radius: 20px;
width: 35px;
height: 35px;
display: flex;
justify-content: center;
align-items: center;
background-color: transparent;
line-height: 1em;
}
.umb-keyboard-shortcuts-overview__overlay-close:hover {
background-color: @blue;
color: #ffffff;
text-decoration: none;
}
.umb-keyboard-shortcuts-overview__overlay-content {

View File

@@ -198,6 +198,7 @@ input.umb-table__input {
padding: 6px 2px;
text-align: left;
overflow:hidden;
}
.umb-table-cell > * {

View File

@@ -9,13 +9,41 @@
color: @white;
position: absolute;
z-index: 10000;
top: 0px;
left: 0px;
margin: 0 !Important;
top: 0;
left: 0;
margin: 0 !important;
padding: 0;
border-radius: 0;
}
@media only screen and (-webkit-min-device-pixel-ratio: 1.5),
only screen and (min-resolution: 144dpi)
{
.login-overlay {
background-image: url(../img/application/logo@2x.png) !important;
}
}
@media only screen and (-webkit-min-device-pixel-ratio: 2),
only screen and (min-resolution: 192dpi)
{
.login-overlay {
background-image: url(../img/application/logo@2x.png) !important;
}
}
@media only screen and (-webkit-min-device-pixel-ratio: 3),
only screen and (min-resolution: 3dppx),
only screen and (min-resolution: 350dpi)
{
.login-overlay {
background-image: url(../img/application/logo@3x.png) !important;
}
}
.login-overlay .umb-modalcolumn {
background: none;
border: none;
@@ -62,7 +90,7 @@
}
#hrOr hr {
margin: 0px;
margin: 0;
border: none;
background-color: @gray;
height: 1px;

View File

@@ -275,11 +275,12 @@ ul.color-picker li a {
.umb-cropper{
position: relative;
padding: 10px;
}
.umb-cropper img, .umb-cropper-gravity img{
position: absolute;
position: relative;
max-width: 100%;
height: auto;
top: 0;
left: 0;
}
@@ -293,19 +294,22 @@ ul.color-picker li a {
left: 0;
cursor: move;
z-index: 6001;
position: absolute;
}
.umb-cropper .viewport{
overflow: hidden;
position: relative;
margin: auto;
max-width: 100%;
height: auto;
}
.umb-cropper-gravity .viewport{
overflow: hidden;
position: relative;
width: 400px;
height: 300px
width: 100%;
height: 100%;
}
@@ -335,27 +339,45 @@ ul.color-picker li a {
opacity: 0.8;
}
.umb-cropper-gravity .overlay i{
.umb-cropper-gravity .overlay i {
font-size: 26px;
line-height: 26px;
opacity: 0.8 !important;
}
.umb-cropper .crop-container{
.umb-cropper .crop-container {
text-align: center;
}
.umb-cropper .crop-slider{
vertical-align: middle;
padding: 10px 50px 10px 50px;
.umb-cropper .crop-slider {
padding: 10px;
border-top: 1px solid @grayLighter;
margin-top: 10px;
display: flex;
align-items: center;
justify-content: center;
flex-wrap: wrap;
@media (min-width: 769px) {
padding: 10px 50px 10px 50px;
}
}
.umb-cropper .crop-slider i{color: @gray;}
.umb-cropper .crop-slider input{
margin-top: 7px;
width: 320px;
.umb-cropper .crop-slider i {
color: @gray;
flex: 0 0 25px;
padding: 0 5px;
box-sizing: border-box;
}
.umb-cropper .crop-slider i:first-of-type {
text-align: right;
}
.umb-cropper .crop-slider input {
flex: 0 1 auto;
}
.umb-cropper-gravity .viewport, .umb-cropper-gravity, .umb-cropper-imageholder {
display: inline-block;
@@ -372,55 +394,98 @@ ul.color-picker li a {
}
.gravity-container .viewport {
width: 494px;
max-width: 600px;
}
.gravity-container .viewport:hover {
cursor: pointer;
}
.imagecropper {
display: flex;
align-items: flex-start;
flex-direction: row;
@media (max-width: 768px) {
flex-direction: column;
float: left;
max-width: 100%;
}
}
.imagecropper .umb-cropper__container {
position: relative;
margin-bottom: 10px;
max-width: 100%;
border: 1px solid #f8f8f8;
@media (min-width: 769px) {
width: 600px;
}
}
.umb-close-cropper {
position: absolute;
top: 3px;
right: 3px;
cursor: pointer;
}
.umb-close-cropper:hover {
opacity: .9;
background: @grayLighter;
}
.imagecropper .umb-sortable-thumbnails {
border-left: 2px solid #f8f8f8;
margin-left: 4px;
padding-left: 2px;
float: left;
width: 100px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.imagecropper .umb-sortable-thumbnails li {
display: block;
}
display: flex;
flex-direction: column;
justify-content: space-between;
.imagecropper .umb-sortable-thumbnails li.current a, .imagecropper .umb-sortable-thumbnails li.current a:hover {
background: #eeeeee;
text-decoration: none;
}
.imagecropper .umb-sortable-thumbnails li:first-of-type {
padding: 8px;
margin-top: 0;
padding-top: 0;
}
.imagecropper .umb-sortable-thumbnails li .crop-name, .imagecropper .umb-sortable-thumbnails li .crop-size {
.imagecropper .umb-sortable-thumbnails li.current {
border-color: @grayLight;
background: @grayLighter;
color: @black;
cursor: pointer;
}
.imagecropper .umb-sortable-thumbnails li:hover,
.imagecropper .umb-sortable-thumbnails li.current:hover {
border-color: @grayLight;
background: @grayLighter;
color: @black;
cursor: pointer;
opacity: .95;
}
.imagecropper .umb-sortable-thumbnails li .crop-name,
.imagecropper .umb-sortable-thumbnails li .crop-size {
display: block;
text-align: left;
font-size: 11px;
font-size: 13px;
line-height: 1;
}
.imagecropper .umb-sortable-thumbnails li .crop-name {
font-weight: bold;
margin: 10px 0 5px;
}
.imagecropper .umb-sortable-thumbnails li .crop-size {
font-size: 10px;
font-style: italic;
color: #666;
}
.imagecropper .umb-sortable-thumbnails li a {
display: block;
padding: 5px;
}
.imagecropper .umb-sortable-thumbnails li a:hover {
background: #f8f8f8;
text-decoration: none;
}
.imagecropper .umb-sortable-thumbnails li a:hover .crop-text {
text-decoration: none;
margin: 0 0 5px;
}
.btn-crop-delete {
@@ -428,20 +493,6 @@ ul.color-picker li a {
text-align: left;
}
.imagecropper .umb-sortable-thumbnails.many {
width: 210px;
}
.imagecropper .umb-sortable-thumbnails.many li {
width: 85px;
float: left;
}
.imagecropper .umb-sortable-thumbnails.many li:nth-child(2) {
margin-top: 0;
padding-top: 0;
}
//
// folder-browser
// --------------------------------------------------

View File

@@ -2,55 +2,48 @@
<div class="umb-panel-header">
<div class="umb-el-wrap umb-panel-buttons">
<div class="form-search">
<i class="icon-search"></i>
<i class="icon-search"></i>
<input type="text"
style="width: 100%"
ng-model="searchTerm"
class="umb-search-field search-query input-block-level"
style="width: 100%"
ng-model="searchTerm"
class="umb-search-field search-query input-block-level"
placeholder="Filter...">
</div>
</div>
</div>
<div class="umb-panel-body with-footer">
<div class="umb-control-group">
<select ng-model="color" class="input-block-level">
<option value="">Black</option>
<option value="color-green">Green</option>
<option value="color-yellow">Yellow</option>
<option value="color-green">Green</option>
<option value="color-yellow">Yellow</option>
<option value="color-orange">Orange</option>
<option value="color-blue">Blue</option>
<option value="color-blue">Blue</option>
<option value="color-red">Red</option>
</select>
<!--
<select class="input-block-level">
<option value="">Black</option>
<option value="color-green">Green</option>
<option value="color-blue">Turquoise</option>
<option value="color-purple">Purple</option>
<option value="color-red">Red</option>
<option value="color-orange">Orange</option>
<option value="color-sky-blue">Sky blue</option>
<option value="color-yellow">Yellow</option>
</select>-->
</div>
<div class="umb-loader" ng-hide="icons"></div>
<umb-load-indicator ng-if="loading"></umb-load-indicator>
<div class="umb-control-group">
<ul class="umb-thumbnails thumbnails" ng-class="color">
<li class="span1" ng-repeat="icon in icons|filter: searchTerm">
<a href="#" title="{{icon}}" class="thumbnail" ng-click="submitClass(icon)" prevent-default>
<i class="{{icon}} large" style="font-size: 32px"></i>
<div class="umb-control-group" ng-show="!loading">
<ul class="umb-iconpicker" ng-class="color" ng-show="icons">
<li class="umb-iconpicker-item" ng-repeat="icon in filtered = (icons | filter: searchTerm) track by $id(icon)">
<a href="#" title="{{icon}}" ng-click="submitClass(icon)" prevent-default>
<i class="{{icon}} large"></i>
</a>
</li>
</ul>
</div>
<umb-empty-state
ng-if="filtered.length === 0"
position="center">
<localize key="defaultdialogs_noIconsFound">No icons were found.</localize>
</umb-empty-state>
</div>
<div class="umb-panel-footer" >
<div class="umb-el-wrap umb-panel-buttons">
<div class="btn-toolbar umb-btn-toolbar pull-right">

View File

@@ -38,14 +38,19 @@
<umb-load-indicator ng-if="loading"></umb-load-indicator>
<div class="umb-control-group" ng-show="!loading">
<ul class="umb-thumbnails thumbnails" ng-class="color">
<li class="span1" ng-repeat="icon in icons|filter: searchTerm">
<a href="#" title="{{icon}}" class="thumbnail" ng-click="selectIcon(icon, color)" prevent-default>
<i class="{{icon}} large" style="font-size: 32px"></i>
<div class="umb-control-group" ng-show="!loading && filtered.length > 0 ">
<ul class="umb-iconpicker" ng-class="color" ng-show="icons">
<li class="umb-iconpicker-item" ng-repeat="icon in filtered = (icons | filter: searchTerm) track by $id(icon)">
<a href="#" title="{{icon}}" ng-click="selectIcon(icon, color)" prevent-default>
<i class="{{icon}} large"></i>
</a>
</li>
</ul>
</div>
<umb-empty-state
ng-if="filtered.length === 0"
position="center">
<localize key="defaultdialogs_noIconsFound">No icons were found.</localize>
</umb-empty-state>
</div>

View File

@@ -1,62 +1,62 @@
<div>
<div id="applications" ng-class="{faded:stickyNavigation}">
<ul class="sections">
<li class="avatar">
<a href="#" ng-click="avatarClick()" hotkey="ctrl+shift+u" title="{{user.name}}" prevent-default>
<img id="avatar-img" ng-src="{{avatar[0].value}}" ng-srcset="{{avatar[1].value}} 2x, {{avatar[2].value}} 3x" />
</a>
</li>
<li ng-repeat="section in sections | limitTo: maxSections" ng-class="{current: section.alias == currentSection}">
<a href="#/{{section.alias}}"
ng-dblclick="sectionDblClick(section)"
ng-click="sectionClick($event, section)"
prevent-default>
<section-icon icon="{{section.cssclass}}"></section-icon>
<span>{{section.name}}</span>
</a>
</li>
<li class="expand" ng-class="{ 'open': showTray === true }" ng-show="needTray">
<a href ng-click="trayClick()">
<i class="icon icon-arrow-right"></i>
</a>
</li>
<li class="help">
<a href class="help" hotkey="ctrl+shift+h" ng-click="helpClick()" prevent-default>
<i class="icon-help-alt"></i>
<span><localize key="sections_help">Help</localize></span>
</a>
</li>
</ul>
</div>
<div id="applications-tray" ng-show="showTray" ng-animate="trayAnimation()">
<ul class="sections sections-tray">
<li ng-repeat="section in sections | limitTo: overflowingSections" ng-class="{current: section.alias == currentSection}">
<a href="#/{{section.alias}}"
ng-dblclick="sectionDblClick(section)"
ng-click="sectionClick($event, section)"
prevent-default>
<section-icon icon="{{section.cssclass}}"></section-icon>
<span>{{section.name}}</span>
</a>
</li>
</ul>
</div>
<umb-overlay
ng-if="helpDialog.show"
model="helpDialog"
view="helpDialog.view"
position="left">
</umb-overlay>
<umb-overlay
ng-if="userDialog.show"
model="userDialog"
view="userDialog.view"
position="left">
</umb-overlay>
</div>
<div>
<div id="applications" ng-class="{faded:stickyNavigation}">
<ul class="sections">
<li class="avatar">
<a href="#" ng-click="avatarClick()" hotkey="ctrl+shift+u" title="{{user.name}}" prevent-default>
<img id="avatar-img" ng-src="{{avatar[0].value}}" ng-srcset="{{avatar[1].value}} 2x, {{avatar[2].value}} 3x" />
</a>
</li>
<li ng-repeat="section in sections | limitTo: maxSections" ng-class="{current: section.alias == currentSection}">
<a href="#/{{section.alias}}"
ng-dblclick="sectionDblClick(section)"
ng-click="sectionClick($event, section)"
prevent-default>
<section-icon icon="{{section.cssclass}}"></section-icon>
<span>{{section.name}}</span>
</a>
</li>
<li class="expand" ng-class="{ 'open': showTray === true }" ng-show="needTray">
<a href ng-click="trayClick()">
<i class="icon icon-arrow-right"></i>
</a>
</li>
<li class="help">
<a href class="help" hotkey="ctrl+shift+h" ng-click="helpClick()" prevent-default>
<i class="icon-help-alt"></i>
<span><localize key="sections_help">Help</localize></span>
</a>
</li>
</ul>
</div>
<div id="applications-tray" ng-show="showTray" ng-animate="trayAnimation()" style="display: none;">
<ul class="sections sections-tray">
<li ng-repeat="section in sections | limitTo: overflowingSections" ng-class="{current: section.alias == currentSection}">
<a href="#/{{section.alias}}"
ng-dblclick="sectionDblClick(section)"
ng-click="sectionClick($event, section)"
prevent-default>
<section-icon icon="{{section.cssclass}}"></section-icon>
<span>{{section.name}}</span>
</a>
</li>
</ul>
</div>
<umb-overlay
ng-if="helpDialog.show"
model="helpDialog"
view="helpDialog.view"
position="left">
</umb-overlay>
<umb-overlay
ng-if="userDialog.show"
model="userDialog"
view="userDialog.view"
position="left">
</umb-overlay>
</div>

View File

@@ -1,12 +1,12 @@
<div class="umb-cropper-gravity">
<div class="gravity-container">
<div class="gravity-container" ng-show="loaded">
<div class="viewport">
<img ng-src="{{src}}" style="max-width: 100%; max-height: 100%" />
<img ng-src="{{src}}" style="max-width: 100%; max-height: 100%" ng-click="setFocalPoint($event)" draggable="false" />
<div class="overlay" ng-style="style()">
</div>
</div>
</div>
</div>
</div>

View File

@@ -1,4 +1,5 @@
<div class="umb-crop-thumbnail-container"
ng-style="{height: height, width: width, overflow: 'hidden', position: 'relative'}">
<div class="umb-crop-thumbnail-container"
ng-style="{height: height, width: width, overflow: 'hidden', position: 'relative'}"
ng-show="loaded">
<img ng-src="{{src}}" alt="{{}}" ng-style="preview" class="noScale" />
</div>
</div>

View File

@@ -1,5 +1,5 @@
<div class="umb-overlay umb-overlay-{{position}}" on-outside-click="closeOverLay()">
<form class="umb-overlay__form" name="overlayForm" ng-submit="submitForm(model)" novalidate val-form-manager>
<ng-form class="umb-overlay__form" name="overlayForm" novalidate val-form-manager>
<div class="umb-overlay-header">
<h4 class="umb-overlay__title">{{model.title}}</h4>
@@ -44,8 +44,9 @@
<umb-button
button-style="success"
label="Confirm"
type="submit"
disabled="!directive.enableConfirmButton">
type="button"
disabled="!directive.enableConfirmButton"
action="submitForm(model)">
</umb-button>
</div>
</div>
@@ -64,10 +65,11 @@
label-key="{{model.submitButtonLabelKey}}"
label="{{model.submitButtonLabel}}"
ng-if="model.submit && model.hideSubmitButton !== true"
type="submit">
type="button"
action="submitForm(model)">
</umb-button>
</div>
</div>
</form>
</ng-form>
</div>

View File

@@ -19,8 +19,8 @@
<div class="umb-keyboard-shortcuts-overview__overlay" ng-if="shortcutOverlay">
<a href="" ng-click="toggleShortcutsOverlay()" data-hotkey="esc">
<i class="umb-keyboard-shortcuts-overview__overlay-close icon-delete"></i>
<a href="" class="umb-keyboard-shortcuts-overview__overlay-close" ng-click="toggleShortcutsOverlay()" data-hotkey="esc" hotkey-when-hidden="true">
<i class="icon-delete"></i>
</a>
<div class="umb-keyboard-shortcuts-overview__overlay-content">

View File

@@ -82,7 +82,8 @@ function ContentEditController($scope, $rootScope, $routeParams, $q, $timeout, $
statusMessage: args.statusMessage,
saveMethod: args.saveMethod,
scope: $scope,
content: $scope.content
content: $scope.content,
action: args.action
}).then(function (data) {
//success
init($scope.content);
@@ -195,15 +196,15 @@ function ContentEditController($scope, $rootScope, $routeParams, $q, $timeout, $
};
$scope.sendToPublish = function () {
return performSave({ saveMethod: contentResource.sendToPublish, statusMessage: "Sending..." });
return performSave({ saveMethod: contentResource.sendToPublish, statusMessage: "Sending...", action: "sendToPublish" });
};
$scope.saveAndPublish = function () {
return performSave({ saveMethod: contentResource.publish, statusMessage: "Publishing..." });
return performSave({ saveMethod: contentResource.publish, statusMessage: "Publishing...", action: "publish" });
};
$scope.save = function () {
return performSave({ saveMethod: contentResource.save, statusMessage: "Saving..." });
return performSave({ saveMethod: contentResource.save, statusMessage: "Saving...", action: "save" });
};
$scope.preview = function (content) {

View File

@@ -4,6 +4,11 @@ function booleanEditorController($scope, $rootScope, assetsService) {
$scope.renderModel = {
value: false
};
if($scope.model.config.default.toString() === "1" && $scope.model && !$scope.model.value) {
$scope.renderModel.value = true;
}
if ($scope.model && $scope.model.value && ($scope.model.value.toString() === "1" || angular.lowercase($scope.model.value) === "true")) {
$scope.renderModel.value = true;
}
@@ -14,7 +19,7 @@ function booleanEditorController($scope, $rootScope, assetsService) {
$scope.$watch("renderModel.value", function (newVal) {
$scope.model.value = newVal === true ? "1" : "0";
});
//here we declare a special method which will be called whenever the value has changed from the server
//this is instead of doing a watch on the model.value = faster
$scope.model.onValueChanged = function (newVal, oldVal) {
@@ -23,4 +28,4 @@ function booleanEditorController($scope, $rootScope, assetsService) {
};
}
angular.module("umbraco").controller("Umbraco.PropertyEditors.BooleanController", booleanEditorController);
angular.module("umbraco").controller("Umbraco.PropertyEditors.BooleanController", booleanEditorController);

View File

@@ -5,6 +5,7 @@ angular.module('umbraco')
function ($rootScope, $routeParams, $scope, $log, mediaHelper, cropperHelper, $timeout, editorState, umbRequestHelper, fileManager, angularHelper) {
var config = angular.copy($scope.model.config);
$scope.imageIsLoaded = false;
//move previously saved value to the editor
if ($scope.model.value) {
@@ -71,6 +72,10 @@ angular.module('umbraco')
}
};
$scope.imageLoaded = function() {
$scope.imageIsLoaded = true;
};
//on image selected, update the cropper
$scope.$on("filesSelected", function (ev, args) {
$scope.model.value = config;

View File

@@ -16,10 +16,10 @@
<div class="imagecropper clearfix">
<div ng-if="currentCrop" style="float:left;" class="clearfix">
<div style="position: relative; margin-bottom: 10px; width: 492px; border: 1px solid #f8f8f8;">
<div ng-if="currentCrop" style="float:left; max-width: 100%;" class="clearfix">
<div class="umb-cropper__container">
<i ng-click="done()" style="opacity: 0.5; position: absolute; top: 3px; right: 3px" class="icon icon-delete btn-round"></i>
<i ng-click="done()" class="icon icon-delete btn-round umb-close-cropper"></i>
<div>
<umb-image-crop height="{{currentCrop.height}}"
@@ -27,7 +27,8 @@
crop="currentCrop.coordinates"
center="model.value.focalPoint"
max-size="450"
src="imageSrc" />
src="imageSrc">
</umb-image-crop>
</div>
<a href style="margin:auto; text-align: center; font-size: 11px;" class="btn btn-link red"
@@ -36,30 +37,36 @@
</a>
</div>
</div>
<div ng-if="!currentCrop" class="umb-cropper-imageholder clearfix">
<umb-image-gravity src="imageSrc"
center="model.value.focalPoint" />
<umb-image-gravity
src="imageSrc"
center="model.value.focalPoint"
on-image-loaded="imageLoaded">
</umb-image-gravity>
<a href class="btn btn-link btn-crop-delete" ng-show="imageIsLoaded" ng-click="clear()"><i class="icon-delete red"></i> <localize key="content_uploadClear">Remove file</localize></a>
</div>
<ul class="umb-sortable-thumbnails cropList clearfix" ng-class="{'many':model.value.crops.length >= 4}">
<li ng-repeat=" (key,value) in model.value.crops" ng-class="{'current':currentCrop.alias === value.alias}">
<a href title="{{value.alias}}: {{value.width}}px x {{value.height}}px" ng-click="crop(value)">
<umb-image-thumbnail center="model.value.focalPoint"
crop="value.coordinates"
src="imageSrc"
height="{{value.height}}"
width="{{value.width}}"
max-size="75"></umb-image-thumbnail>
<ul class="umb-sortable-thumbnails cropList clearfix">
<li ng-repeat=" (key,value) in model.value.crops" ng-class="{'current':currentCrop.alias === value.alias}" ng-click="crop(value)">
<umb-image-thumbnail center="model.value.focalPoint"
crop="value.coordinates"
src="imageSrc"
height="{{value.height}}"
width="{{value.width}}"
max-size="75">
</umb-image-thumbnail>
<div class="crop-information">
<span class="crop-name crop-text">{{value.alias}}</span>
<span class="crop-size crop-text">{{value.width}}px x {{value.height}}px</span>
</a>
</div>
</li>
</ul>
</div>
<a href class="btn btn-link btn-crop-delete" ng-click="clear()"><i class="icon-delete red"></i> <localize key="content_uploadClear">Remove file</localize></a>
</div>
</div>
</div>

View File

@@ -6,7 +6,9 @@
var vm = this;
vm.nodeId = $scope.contentId;
vm.acceptedFileTypes = mediaHelper.formatFileTypes(Umbraco.Sys.ServerVariables.umbracoSettings.imageFileTypes);
//vm.acceptedFileTypes = mediaHelper.formatFileTypes(Umbraco.Sys.ServerVariables.umbracoSettings.imageFileTypes);
//instead of passing in a whitelist, we pass in a blacklist by adding ! to the ext
vm.acceptedFileTypes = mediaHelper.formatFileTypes(Umbraco.Sys.ServerVariables.umbracoSettings.disallowedUploadFiles).replace(/./g, "!.");
vm.maxFileSize = Umbraco.Sys.ServerVariables.umbracoSettings.maxFileSize + "KB";
vm.activeDrag = false;
vm.isRecycleBin = $scope.contentId === '-21' || $scope.contentId === '-20';

View File

@@ -60,6 +60,7 @@ function listViewController($rootScope, $scope, $routeParams, $injector, $cookie
};
$scope.options = {
displayAtTabNumber: $scope.model.config.displayAtTabNumber ? $scope.model.config.displayAtTabNumber : 1,
pageSize: $scope.model.config.pageSize ? $scope.model.config.pageSize : 10,
pageNumber: ($routeParams.page && Number($routeParams.page) != NaN && Number($routeParams.page) > 0) ? $routeParams.page : 1,
filter: '',

View File

@@ -222,14 +222,12 @@
<Name>System.Data</Name>
</Reference>
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Data.SqlServerCe, Version=4.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<HintPath>..\packages\SqlServerCE.4.0.0.0\lib\System.Data.SqlServerCe.dll</HintPath>
<SpecificVersion>False</SpecificVersion>
<Reference Include="System.Data.SqlServerCe, Version=4.0.0.1, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<HintPath>..\packages\SqlServerCE.4.0.0.1\lib\System.Data.SqlServerCe.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Data.SqlServerCe.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<HintPath>..\packages\SqlServerCE.4.0.0.0\lib\System.Data.SqlServerCe.Entity.dll</HintPath>
<SpecificVersion>False</SpecificVersion>
<Reference Include="System.Data.SqlServerCe.Entity, Version=4.0.0.1, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<HintPath>..\packages\SqlServerCE.4.0.0.1\lib\System.Data.SqlServerCe.Entity.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Drawing" />
@@ -2016,14 +2014,9 @@
<Content Include="Umbraco\Translation\default.aspx" />
<Content Include="Umbraco\Translation\preview.aspx" />
<Content Include="Umbraco\Translation\xml.aspx" />
<Content Include="Umbraco\Create\content.ascx" />
<Content Include="Umbraco\Create\language.ascx">
<SubType>UserControl</SubType>
</Content>
<Content Include="Umbraco\Create\member.ascx" />
<Content Include="Umbraco\Create\nodeType.ascx">
<SubType>UserControl</SubType>
</Content>
<Content Include="Umbraco\Create\simple.ascx" />
<Content Include="Umbraco\Create\xslt.ascx">
<SubType>UserControl</SubType>
@@ -2405,10 +2398,10 @@
</PropertyGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PreBuildEvent>
</PreBuildEvent>
<PostBuildEvent>xcopy "$(ProjectDir)"..\packages\SqlServerCE.4.0.0.0\amd64\*.* "$(TargetDir)amd64\" /Y /F /E /D
xcopy "$(ProjectDir)"..\packages\SqlServerCE.4.0.0.0\x86\*.* "$(TargetDir)x86\" /Y /F /E /D</PostBuildEvent>
<PreBuildEvent>xcopy "$(ProjectDir)"..\packages\SqlServerCE.4.0.0.1\amd64\*.* "$(TargetDir)amd64\" /Y /F /E /I /C /D
xcopy "$(ProjectDir)"..\packages\SqlServerCE.4.0.0.1\x86\*.* "$(TargetDir)x86\" /Y /F /E /I /C /D</PreBuildEvent>
<PostBuildEvent>
</PostBuildEvent>
</PropertyGroup>
<Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" />
@@ -2418,9 +2411,9 @@ xcopy "$(ProjectDir)"..\packages\SqlServerCE.4.0.0.0\x86\*.* "$(TargetDir)x86\"
<WebProjectProperties>
<UseIIS>True</UseIIS>
<AutoAssignPort>True</AutoAssignPort>
<DevelopmentServerPort>7400</DevelopmentServerPort>
<DevelopmentServerPort>7410</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>http://localhost:7400</IISUrl>
<IISUrl>http://localhost:7410</IISUrl>
<NTLMAuthentication>False</NTLMAuthentication>
<UseCustomServer>False</UseCustomServer>
<CustomServerUrl>

View File

@@ -788,29 +788,46 @@ Vennlig hilsen Umbraco roboten
</area>
<area alias="grid">
<key alias="insertControl">Sett inn element</key>
<key alias="addRows">Velg ett oppsett for denne seksjonen</key>
<key alias="addElement"><![CDATA[Kom i gang ved å trykke på <i class=" icon icon-add blue"></i> nedenfor og legg til det første elementet]]></key>
<key alias="chooseLayout">Velg layout</key>
<key alias="addRows">Legg til rad</key>
<key alias="addElement">Legg til innhold</key>
<key alias="dropElement">Slipp innhold</key>
<key alias="settingsApplied">Raden har tilpasset design</key>
<key alias="contentNotAllowed">Innholdstypen er ikke tillatt her</key>
<key alias="contentAllowed">Innholdstypen er tillatt her</key>
<key alias="clickToEmbed">Klikk for å bygge inn</key>
<key alias="clickToInsertImage">Klikk for å sette inn et bilde</key>
<key alias="placeholderImageCaption">Bildetekst...</key>
<key alias="placeholderWriteHere">Skriv her...</key>
<key alias="gridLayouts">Rutenettoppsett</key>
<key alias="gridLayoutsDetail">Et oppsett er det overordnede arbeidsområdet til ditt rutenett - du vil typisk kun behøve ét eller to</key>
<key alias="gridLayoutsDetail">Et oppsett er det overordnede arbeidsområdet til ditt rutenett - du vil typisk kun behøve ett eller to</key>
<key alias="addGridLayout">Legg til rutenettoppsett</key>
<key alias="addGridLayoutDetail">Juster oppsettet ved at justere kolonnebredder og legg til ytterligere seksjoner</key>
<key alias="addGridLayoutDetail">Juster oppsettet ved å konfigurere kolonnebredder og legge til ytterligere seksjoner</key>
<key alias="rowConfigurations">Radkonfigurasjoner</key>
<key alias="rowConfigurationsDetail">Rader er forhåndsdefinerte celler arrangert vannrett</key>
<key alias="addRowConfiguration">Legg til radkonfigurasjon</key>
<key alias="addRowConfigurationDetail">Juster raden ved å sette celle bredder og legge til flere celler</key>
<key alias="addRowConfigurationDetail">Juster raden ved å sette cellebredder og legge til flere celler</key>
<key alias="columns">Kolonner</key>
<key alias="columnsDetails">Totale antallet kolonner i rutenettet</key>
<key alias="columnsDetails">Totalt antall kolonner i rutenettet</key>
<key alias="settings">Innstillinger</key>
<key alias="settingsDetails">Konfigurer hvilke innstillinger brukeren kan endre</key>
<key alias="styles">Stiler</key>
<key alias="stylesDetails">Konfigurer hvilke stiler redaktørene kan endre</key>
<key alias="settingDialogDetails">Innstillingene lagres kun når json-konfigurasjonen er gyldig</key>
<key alias="settingDialogDetails">Innstillingene lagres kun når konfigurasjonen er gyldig</key>
<key alias="allowAllEditors">Tillatt alle editorer</key>
<key alias="allowAllRowConfigurations">Tillat alle radkonfigurasjoner</key>
<key alias="setAsDefault">Bruk som standard</key>
<key alias="chooseExtra">Velg ekstra</key>
<key alias="chooseDefault">Velg standard</key>
<key alias="areAdded">er lagt til</key>
</area>
<area alias="templateEditor">
<key alias="alternativeField">Alternativt felt</key>

View File

@@ -32,7 +32,7 @@
<package id="Newtonsoft.Json" version="6.0.8" targetFramework="net45" />
<package id="Owin" version="1.0" targetFramework="net45" />
<package id="SharpZipLib" version="0.86.0" targetFramework="net45" />
<package id="SqlServerCE" version="4.0.0.0" targetFramework="net45" />
<package id="SqlServerCE" version="4.0.0.1" targetFramework="net45" />
<package id="System.Collections.Immutable" version="1.1.36" targetFramework="net45" />
<package id="System.Reflection.Metadata" version="1.0.21" targetFramework="net45" />
<package id="Umbraco.ModelsBuilder" version="3.0.0" targetFramework="net45" />

View File

@@ -265,6 +265,7 @@
<key alias="selectContent">Select content</key>
<key alias="selectMember">Select member</key>
<key alias="selectMemberGroup">Select member group</key>
<key alias="noIconsFound">No icons were found</key>
<key alias="noMacroParams">There are no parameters for this macro</key>

View File

@@ -1,27 +0,0 @@
<%@ Control Language="c#" AutoEventWireup="True" Codebehind="content.ascx.cs" Inherits="umbraco.cms.presentation.create.controls.content" TargetSchema="http://schemas.microsoft.com/intellisense/ie5" %>
<asp:literal id="typeJs" runat="server"/>
<div><%=umbraco.ui.Text("name")%>:<br /></div>
<asp:TextBox id="rename" Runat="server" CssClass="bigInput"></asp:TextBox><br /><br />
<asp:RequiredFieldValidator id="RequiredFieldValidator1" ErrorMessage="*" ControlToValidate="rename" runat="server">*</asp:RequiredFieldValidator>
<span style="margin-left: -7px;"><%=umbraco.ui.Text("choose")%> <%=umbraco.ui.Text("documentType")%>:<br /></span>
<asp:ListBox id="nodeType" Runat="server" cssClass="bigInput" Rows="1" SelectionMode="Single"></asp:ListBox>
<asp:RequiredFieldValidator id="RequiredFieldValidator2" ErrorMessage="*" ControlToValidate="nodeType" runat="server">*</asp:RequiredFieldValidator>
<br />
<!-- added to support missing postback on enter in IE -->
<asp:TextBox runat="server" style="visibility:hidden;display:none;" ID="Textbox1"/>
<div id="typeDescription" class="createDescription">
<asp:Literal ID="descr" runat="server"></asp:Literal>
</div>
<div style="margin-right: 15px;">
<asp:Button id="sbmt" Runat="server" style="Width: 90px; margin-right: 6px;" onclick="sbmt_Click"></asp:Button>
<em> <%= umbraco.ui.Text("or") %> </em>
<a href="#" style="color: Blue; margin-left: 6px;" onclick="UmbClientMgr.closeModalWindow()"><%=umbraco.ui.Text("cancel")%></a>
<!--
<input type="button" value="" onClick="if (confirm('<%=umbraco.ui.Text("areyousure")%>')) window.close()" style="width: 90px; margin-left: 6px;"/>
-->
</div>

View File

@@ -1,48 +0,0 @@
<%@ Control Language="c#" AutoEventWireup="True" CodeBehind="member.ascx.cs" Inherits="umbraco.cms.presentation.create.controls.member"
TargetSchema="http://schemas.microsoft.com/intellisense/ie5" %>
<asp:ValidationSummary runat="server" DisplayMode="BulletList" ID="validationSummary"
CssClass="error"></asp:ValidationSummary>
<asp:Literal ID="nameLiteral" runat="server"></asp:Literal>:<asp:RequiredFieldValidator
ID="nameRequired" ErrorMessage="*" ControlToValidate="rename" runat="server">*</asp:RequiredFieldValidator>
<br />
<asp:TextBox ID="rename" runat="server" Width="350px" CssClass="bigInput"></asp:TextBox>
<asp:Panel ID="memberChooser" runat="server">
<%=umbraco.ui.Text("choose")%>
<%=umbraco.ui.Text("membertype")%>:<asp:RequiredFieldValidator ID="memberTypeRequired" ErrorMessage="*" ControlToValidate="nodeType"
runat="server">*</asp:RequiredFieldValidator><br />
<asp:ListBox ID="nodeType" runat="server" Width="350px" CssClass="bigInput" Rows="1"
SelectionMode="Single"></asp:ListBox>
</asp:Panel>
<p>
Login Name:<asp:RequiredFieldValidator ID="loginRequired" ErrorMessage="*" ControlToValidate="Login"
runat="server">*</asp:RequiredFieldValidator>
<asp:CustomValidator ID="loginExistsCheck" runat="server" ErrorMessage="*" ControlToValidate="Login" ValidateEmptyText="false" OnServerValidate="LoginExistsCheck"></asp:CustomValidator>
<br />
<asp:TextBox ID="Login" runat="server" Width="350px" CssClass="bigInput"></asp:TextBox><br />
</p>
<p>
E-mail:
<asp:RequiredFieldValidator ID="emailRequired" ErrorMessage="*" ControlToValidate="Email"
runat="server">*</asp:RequiredFieldValidator>
<asp:CustomValidator ID="emailExistsCheck" runat="server" ErrorMessage="*" ControlToValidate="Email" ValidateEmptyText="false" OnServerValidate="EmailExistsCheck"></asp:CustomValidator>
<asp:CustomValidator runat="server" ID="EmailValidator" OnServerValidate="EmailValidator_OnServerValidate"
ControlToValidate="Email"
ErrorMessage="Invalid email address"
Display="None"/>
<br />
<asp:TextBox ID="Email" runat="server" Width="350px" CssClass="bigInput"></asp:TextBox><br />
</p>
<p>
Password: <em>
<asp:Literal runat="server" ID="PasswordRules"></asp:Literal></em><asp:RequiredFieldValidator
ID="passwordRequired" ControlToValidate="Password" runat="server">*</asp:RequiredFieldValidator><br />
<asp:TextBox ID="Password" runat="server" Width="350px" CssClass="bigInput"></asp:TextBox><br />
</p>
<!-- added to support missing postback on enter in IE -->
<asp:TextBox runat="server" Style="visibility: hidden; display: none;" ID="Textbox1" />
<div style="padding-top: 15px;">
<asp:Button ID="sbmt" runat="server" Style="margin-top: 14px" Width="90" OnClick="sbmt_Click">
</asp:Button>
&nbsp; <em>
<%= umbraco.ui.Text("or") %></em> &nbsp;<a href="#" style="color: blue" onclick="UmbClientMgr.closeModalWindow()"><%=umbraco.ui.Text("cancel")%></a>
</div>

View File

@@ -1,32 +0,0 @@
<%@ Control Language="c#" AutoEventWireup="True" Codebehind="nodeType.ascx.cs" Inherits="umbraco.cms.presentation.create.controls.nodeType" TargetSchema="http://schemas.microsoft.com/intellisense/ie5"%>
<%@ Register TagPrefix="cc1" Namespace="umbraco.uicontrols" Assembly="controls" %>
<cc1:Pane runat="server">
<cc1:PropertyPanel runat="server" id="pp_name" text="Name">
<asp:TextBox id="rename" Runat="server" CssClass="bigInput input-large-type input-block-level"></asp:TextBox>
<asp:RequiredFieldValidator id="RequiredFieldValidator1" ErrorMessage="*" ControlToValidate="rename" runat="server">*</asp:RequiredFieldValidator>
</cc1:PropertyPanel>
<cc1:PropertyPanel runat="server" text="Master Document Type" ID="pp_MasterDocumentType">
<asp:ListBox id="masterType" Runat="server" cssClass="bigInput input-large-type input-block-level" Rows="1" SelectionMode="Single"></asp:ListBox>
<asp:Literal ID="masterTypePreDefined" runat="server" Visible="false"></asp:Literal>
</cc1:PropertyPanel>
<cc1:PropertyPanel runat="server">
<asp:CheckBox ID="createTemplate" Runat="server" Checked="true" Text="Create matching template"></asp:CheckBox>
</cc1:PropertyPanel>
<asp:TextBox runat="server" style="visibility:hidden;display:none;" ID="Textbox1"/>
<asp:CustomValidator ID="CustomValidation1" ErrorMessage="* A document type with this name/alias already exists" OnServerValidate="validationDoctypeName" ControlToValidate="rename" ForeColor="red" runat="server" />
<asp:CustomValidator ID="CustomValidation2" ErrorMessage="<br/>* The name of the document type will result in an invalid alias" OnServerValidate="validationDoctypeAlias" ControlToValidate="rename" ForeColor="red" runat="server" />
</cc1:Pane>
<cc1:Pane runat="server" CssClass="btn-toolbar umb-btn-toolbar">
<a href="#" class="btn btn-link" onclick="UmbClientMgr.closeModalWindow()"><%=umbraco.ui.Text("cancel")%></a>
<asp:Button id="sbmt" Runat="server" CssClass="btn btn-primary" onclick="sbmt_Click"></asp:Button>
</cc1:Pane>

View File

@@ -5,11 +5,11 @@
<%@ Register TagPrefix="CD" Namespace="ClientDependency.Core.Controls" Assembly="ClientDependency.Core" %>
<asp:Content ContentPlaceHolderID="head" runat="server">
<CD:CssInclude ID="CssInclude1" runat="server" FilePath="Editors/EditMacro.css" PathNameAlias="UmbracoClient" />
<script type="text/javascript">
//handles the change selection of the drop downs to populate the text box
(function($) {
$(document).ready(function () {
@@ -23,8 +23,8 @@
$(".fileChooser input[type='text']").not(txt).val("");
//reset other drop downs
$(".fileChooser select").not($(this)).val("");
});
});
UmbClientMgr.appActions().bindSaveShortCut();
// U4-667: Make the "Render content in editor" checkbox dependent on the "Use in editor checkbox"
@@ -42,10 +42,10 @@
toggle();
});
});
})(jQuery);
</script>
</asp:Content>
<asp:Content ContentPlaceHolderID="body" runat="server">
@@ -57,10 +57,10 @@
</cc1:PropertyPanel>
<cc1:PropertyPanel runat="server" Text="Alias">
<asp:TextBox ID="macroAlias" runat="server" CssClass="guiInputText"></asp:TextBox>
</cc1:PropertyPanel>
</cc1:PropertyPanel>
</cc1:Pane>
<cc1:Pane ID="Pane1_2" runat="server" title="Choose a file to render" CssClass="fileChooser">
<cc1:PropertyPanel runat="server" Text="MVC Partial view">
@@ -93,16 +93,16 @@
(Assembly)<br />
<asp:TextBox ID="macroType" runat="server" CssClass="guiInputText"></asp:TextBox>
(Type)
<asp:PlaceHolder ID="assemblyBrowser" runat="server"></asp:PlaceHolder>
<asp:PlaceHolder ID="assemblyBrowser" runat="server"></asp:PlaceHolder>
</asp:PlaceHolder>
</cc1:Pane>
<cc1:Pane ID="Pane1_3" runat="server" Title="Editor settings">
<cc1:PropertyPanel runat="server" Text="Use in rich text editor and the grid">
<asp:CheckBox ID="macroEditor" runat="server" Text="Yes"></asp:CheckBox>
</cc1:PropertyPanel>
<cc1:PropertyPanel runat="server" Text="Render in rich text editor and the grid">
<asp:CheckBox ID="macroRenderContent" runat="server" Text="Yes"></asp:CheckBox>
</cc1:PropertyPanel>
@@ -137,6 +137,9 @@
<th>
<%=umbraco.ui.Text("general", "type",UmbracoUser)%>
</th>
<th>
<%=umbraco.ui.Text("general", "sort",UmbracoUser)%>
</th>
<th></th>
</tr>
</thead>
@@ -144,23 +147,28 @@
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<td>
<input type="hidden" id="macroPropertyID" runat="server" value='<%#Eval("Id")%>'
name="macroPropertyID" />
<asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ControlToValidate="macroPropertyAlias" Display="Dynamic" ForeColor="#b94a48">Required<br/></asp:RequiredFieldValidator>
<asp:TextBox runat="server" ID="macroPropertyAlias" Text='<%#Eval("Alias")%>' />
<asp:TextBox runat="server" ID="macroPropertyAlias" CLASS="-full-width-input" Text='<%#Eval("Alias")%>' />
</td>
<td>
<asp:RequiredFieldValidator ID="RequiredFieldValidator2" runat="server" ControlToValidate="macroPropertyName" Display="Dynamic" ForeColor="#b94a48">Required<br/></asp:RequiredFieldValidator>
<asp:TextBox runat="server" ID="macroPropertyName" Text='<%#Eval("Name")%>' />
<asp:TextBox runat="server" ID="macroPropertyName" CLASS="-full-width-input" Text='<%#Eval("Name")%>' />
</td>
<td>
<asp:RequiredFieldValidator ID="RequiredFieldValidator3" runat="server" ControlToValidate="macroPropertyType" Display="Dynamic" ForeColor="#b94a48">Required<br/></asp:RequiredFieldValidator>
<asp:DropDownList OnPreRender="AddChooseList" runat="server" ID="macroPropertyType"
DataTextFormatString="" DataTextField='Name' DataValueField="Alias">
</asp:DropDownList>
</td>
<td>
<asp:RequiredFieldValidator ID="RequiredFieldValidator6" runat="server" ControlToValidate="macroPropertySortOrder" Display="Dynamic" ForeColor="#b94a48">Required<br/></asp:RequiredFieldValidator>
<asp:RegularExpressionValidator ID="RegularExpressionValidator1" runat="server" ControlToValidate="macroPropertySortOrder" Display="Dynamic" ForeColor="#b94a48" ValidationExpression="^\d+$">Numbers only<br/></asp:RegularExpressionValidator>
<asp:TextBox runat="server" ID="macroPropertySortOrder" CLASS="-full-width-input" Text='<%#Eval("SortOrder")%>' />
</td>
<td>
<asp:Button OnClick="deleteMacroProperty" ID="delete" Text="Delete" runat="server" CssClass="btn btn-default delete-button" />
</td>
@@ -170,20 +178,23 @@
<tr>
<td>
<asp:RequiredFieldValidator ID="RequiredFieldValidator1" EnableViewState="false" Enabled="false" EnableClientScript="false" runat="server" ControlToValidate="macroPropertyAliasNew" Display="Dynamic" ForeColor="#b94a48">Required<br/></asp:RequiredFieldValidator>
<asp:TextBox runat="server" ID="macroPropertyAliasNew" PlaceHolder='New Alias' />
<asp:TextBox runat="server" ID="macroPropertyAliasNew" CLASS="-full-width-input" PlaceHolder='New Alias' />
</td>
<td>
<asp:RequiredFieldValidator ID="RequiredFieldValidator4" EnableViewState="false" Enabled="false" EnableClientScript="false" runat="server" ControlToValidate="macroPropertyNameNew" Display="Dynamic" ForeColor="#b94a48">Required<br/></asp:RequiredFieldValidator>
<asp:TextBox runat="server" ID="macroPropertyNameNew" PlaceHolder='New Name' />
<asp:TextBox runat="server" ID="macroPropertyNameNew" CLASS="-full-width-input" PlaceHolder='New Name' />
</td>
<td>
<asp:RequiredFieldValidator ID="RequiredFieldValidator5" EnableViewState="false" Enabled="false" EnableClientScript="false" runat="server" ControlToValidate="macroPropertyTypeNew" Display="Dynamic" ForeColor="#b94a48">Required<br/></asp:RequiredFieldValidator>
<asp:DropDownList OnPreRender="AddChooseList" runat="server" ID="macroPropertyTypeNew"
DataTextField="Name"
DataValueField="Alias"
DataTextField="Name"
DataValueField="Alias"
DataSource='<%# GetMacroParameterEditors()%>'>
</asp:DropDownList>
</td>
<td>
<%-- The macro parameter will automatically get sort order when created. --%>
</td>
<td>
<asp:Button ID="createNew" Text="Add" runat="server" CssClass="btn btn-default add-button" OnClick="macroPropertyCreate" />
</td>

View File

@@ -256,7 +256,7 @@ namespace Umbraco.Web.UI.Umbraco.Dialogs
ClientTools.SyncTree(_content.Path, true);
// Reload the page if the content was already being viewed
ClientTools.ReloadContentFrameUrlIfPathLoaded("/editContent.aspx?id=" + _content.Id);
ClientTools.ReloadLocation();
// Display success message
SuccessMessage.Text = global::umbraco.ui.Text("changeDocType", "successMessage").Replace("[new type]", "<strong>" + newContentType.Name + "</strong>");

View File

@@ -151,7 +151,6 @@ Umbraco.Sys.registerNamespace("Umbraco.Application");
/** This is used to launch an angular based modal window instead of the legacy window */
openAngularModalWindow: function (options) {
if (!this.mainWindow().UmbClientMgr) {
throw "An angular modal window can only be launched when the modal is running within the main Umbraco application";
}
@@ -173,6 +172,12 @@ Umbraco.Sys.registerNamespace("Umbraco.Application");
},
reloadLocation: function () {
if (this.mainWindow().UmbClientMgr) {
this.mainWindow().UmbClientMgr.reloadLocation();
}
},
openModalWindow: function(url, name, showHeader, width, height, top, leftOffset, closeTriggers, onCloseCallback) {
//need to create the modal on the top window if the top window has a client manager, if not, create it on the current window

View File

@@ -22,11 +22,11 @@
s = s.replace(/\-/g, "/");
//all of these basically transform the string into year-month-day since that
//is what JS understands when creating a Date object
if (c.dateFormat.indexOf("dd/MM/yyyy") == 0 || c.dateFormat.indexOf("dd-MM-yyyy") == 0) {
s = s.replace(/(\d{1,2})[\/\-](\d{1,2})[\/\-](\d{4})/, "$3-$2-$1");
if (c.dateFormat.indexOf("dd/MM/yyyy") == 0 || c.dateFormat.indexOf("dd-MM-yyyy") == 0 || c.dateFormat.indexOf("dd.MM.yyyy") == 0) {
s = s.replace(/(\d{1,2})[\/\-\.](\d{1,2})[\/\-\.](\d{4})/, "$3-$2-$1");
}
else if (c.dateFormat.indexOf("dd/MM/yy") == 0 || c.dateFormat.indexOf("dd-MM-yy") == 0) {
s = s.replace(/(\d{1,2})[\/\-](\d{1,2})[\/\-](\d{2})/, "$3-$2-$1");
else if (c.dateFormat.indexOf("dd/MM/yy") == 0 || c.dateFormat.indexOf("dd-MM-yy") == 0 || c.dateFormat.indexOf("dd.MM.yy") == 0) {
s = s.replace(/(\d{1,2})[\/\-\.](\d{1,2})[\/\-\.](\d{2})/, "$3-$2-$1");
}
else if (c.dateFormat.indexOf("MM/dd/yyyy") == 0 || c.dateFormat.indexOf("MM-dd-yyyy") == 0) {
s = s.replace(/(\d{1,2})[\/\-](\d{1,2})[\/\-](\d{4})/, "$3-$1-$2");
@@ -118,4 +118,4 @@
})(jQuery);
})(jQuery);

View File

@@ -49,7 +49,7 @@ namespace Umbraco.Web.Cache
userCache.Result.ClearCacheItem(RepositoryBase.GetCacheIdKey<IUser>(id));
if (UserPermissionsCache)
UserPermissionsCache.Result.ClearCacheItem(string.Format("{0}{1}", CacheKeys.UserPermissionsCacheKey, id));
UserPermissionsCache.Result.ClearCacheByKeySearch(string.Format("{0}{1}", CacheKeys.UserPermissionsCacheKey, id));
base.Remove(id);
}

View File

@@ -46,7 +46,7 @@ namespace Umbraco.Web.Cache
public override void Remove(int id)
{
if (UserPermissionsCache)
UserPermissionsCache.Result.ClearCacheItem(string.Format("{0}{1}", CacheKeys.UserPermissionsCacheKey, id));
UserPermissionsCache.Result.ClearCacheByKeySearch(string.Format("{0}{1}", CacheKeys.UserPermissionsCacheKey, id));
base.Remove(id);
}

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
@@ -34,7 +35,7 @@ namespace Umbraco.Web.Editors
throw new HttpResponseException(HttpStatusCode.NotFound);
}
return Mapper.Map<IEnumerable<MacroParameter>>(macro);
return Mapper.Map<IEnumerable<MacroParameter>>(macro).OrderBy(x => x.SortOrder);
}
/// <summary>

View File

@@ -0,0 +1,15 @@
using System.Web;
namespace Umbraco.Web
{
/// <summary>
/// Used to retrieve the HttpContext
/// </summary>
/// <remarks>
/// NOTE: This has a singleton lifespan
/// </remarks>
public interface IHttpContextAccessor
{
HttpContextBase Value { get; }
}
}

View File

@@ -2,7 +2,10 @@ namespace Umbraco.Web
{
/// <summary>
/// Used to retrieve the Umbraco context
/// </summary>
/// </summary>
/// <remarks>
/// NOTE: This has a singleton lifespan
/// </remarks>
public interface IUmbracoContextAccessor
{
UmbracoContext Value { get; }

View File

@@ -124,7 +124,7 @@ namespace Umbraco.Web.Macros
var routeVals = new RouteData();
routeVals.Values.Add("controller", "PartialViewMacro");
routeVals.Values.Add("action", "Index");
routeVals.DataTokens.Add("umbraco-context", umbCtx); //required for UmbracoViewPage
routeVals.DataTokens.Add(Umbraco.Core.Constants.Web.UmbracoContextDataToken, umbCtx); //required for UmbracoViewPage
//lets render this controller as a child action
var viewContext = new ViewContext {ViewData = new ViewDataDictionary()};;

View File

@@ -20,6 +20,9 @@ namespace Umbraco.Web.Models.ContentEditing
[DataMember(Name = "name")]
public string Name { get; set; }
[DataMember(Name = "sortOrder")]
public int SortOrder { get; set; }
/// <summary>
/// The editor view to render for this parameter

View File

@@ -114,9 +114,6 @@ namespace Umbraco.Web.Models.Mapping
//re-assign
genericProps.Properties = contentProps;
}
/// <summary>
@@ -187,12 +184,38 @@ namespace Umbraco.Web.Models.Mapping
});
listViewTab.Properties = listViewProperties;
//Is there a better way?
var tabs = new List<Tab<ContentPropertyDisplay>>();
tabs.Add(listViewTab);
tabs.AddRange(display.Tabs);
display.Tabs = tabs;
SetChildItemsTabPosition(display, listViewConfig, listViewTab);
}
private static void SetChildItemsTabPosition<TPersisted>(TabbedContentItem<ContentPropertyDisplay, TPersisted> display,
IDictionary<string, object> listViewConfig,
Tab<ContentPropertyDisplay> listViewTab)
where TPersisted : IContentBase
{
// Find position of tab from config
var tabIndexForChildItems = 0;
if (listViewConfig["displayAtTabNumber"] != null && int.TryParse((string)listViewConfig["displayAtTabNumber"], out tabIndexForChildItems))
{
// Tab position is recorded 1-based but we insert into collection 0-based
tabIndexForChildItems--;
// Ensure within bounds
if (tabIndexForChildItems < 0)
{
tabIndexForChildItems = 0;
}
if (tabIndexForChildItems > display.Tabs.Count())
{
tabIndexForChildItems = display.Tabs.Count();
}
}
// Recreate tab list with child items tab at configured position
var tabs = new List<Tab<ContentPropertyDisplay>>();
tabs.AddRange(display.Tabs);
tabs.Insert(tabIndexForChildItems, listViewTab);
display.Tabs = tabs;
}
protected override IEnumerable<Tab<ContentPropertyDisplay>> ResolveCore(IContentBase content)

View File

@@ -110,7 +110,7 @@ namespace Umbraco.Web.Mvc
//match this area
controllerPluginRoute.DataTokens.Add("area", area.AreaName);
controllerPluginRoute.DataTokens.Add("umbraco", umbracoTokenValue); //ensure the umbraco token is set
controllerPluginRoute.DataTokens.Add(Core.Constants.Web.UmbracoDataToken, umbracoTokenValue); //ensure the umbraco token is set
return controllerPluginRoute;
}

View File

@@ -0,0 +1,50 @@
using System.Web.Mvc;
namespace Umbraco.Web.Mvc
{
public static class ControllerContextExtensions
{
/// <summary>
/// Tries to get the Umbraco context from the whole ControllerContext hierarchy based on data tokens and if that fails
/// it will attempt to fallback to retrieving it from the HttpContext.
/// </summary>
/// <param name="controllerContext"></param>
/// <returns></returns>
public static UmbracoContext GetUmbracoContext(this ControllerContext controllerContext)
{
var umbCtx = controllerContext.RouteData.GetUmbracoContext();
if (umbCtx != null) return umbCtx;
if (controllerContext.ParentActionViewContext != null)
{
//recurse
return controllerContext.ParentActionViewContext.GetUmbracoContext();
}
//fallback to getting from HttpContext
return controllerContext.HttpContext.GetUmbracoContext();
}
/// <summary>
/// Find a data token in the whole ControllerContext hierarchy of execution
/// </summary>
/// <param name="controllerContext"></param>
/// <param name="dataTokenName"></param>
/// <returns></returns>
internal static object GetDataTokenInViewContextHierarchy(this ControllerContext controllerContext, string dataTokenName)
{
if (controllerContext.RouteData.DataTokens.ContainsKey(dataTokenName))
{
return controllerContext.RouteData.DataTokens[dataTokenName];
}
if (controllerContext.ParentActionViewContext != null)
{
//recurse!
return controllerContext.ParentActionViewContext.GetDataTokenInViewContextHierarchy(dataTokenName);
}
return null;
}
}
}

View File

@@ -5,24 +5,8 @@ using System.Web.Mvc;
namespace Umbraco.Web.Mvc
{
internal static class ControllerExtensions
internal static class ControllerExtensions
{
internal static object GetDataTokenInViewContextHierarchy(this ControllerContext controllerContext, string dataTokenName)
{
if (controllerContext.RouteData.DataTokens.ContainsKey(dataTokenName))
{
return controllerContext.RouteData.DataTokens[dataTokenName];
}
if (controllerContext.ParentActionViewContext != null)
{
//recurse!
return controllerContext.ParentActionViewContext.GetDataTokenInViewContextHierarchy(dataTokenName);
}
return null;
}
/// <summary>
/// Return the controller name from the controller type
/// </summary>

View File

@@ -1,5 +1,6 @@
using System;
using System.Globalization;
using System.Text;
using System.Web.Mvc;
using Umbraco.Core;
using Umbraco.Core.Models;
@@ -19,10 +20,20 @@ namespace Umbraco.Web.Mvc
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
object model;
if (controllerContext.RouteData.DataTokens.TryGetValue("umbraco", out model) == false)
if (controllerContext.RouteData.DataTokens.TryGetValue(Core.Constants.Web.UmbracoDataToken, out model) == false)
return null;
var culture = UmbracoContext.Current.PublishedContentRequest.Culture;
//default culture
var culture = CultureInfo.CurrentCulture;
var umbracoContext = controllerContext.GetUmbracoContext()
?? UmbracoContext.Current;
if (umbracoContext != null && umbracoContext.PublishedContentRequest != null)
{
culture = umbracoContext.PublishedContentRequest.Culture;
}
return BindModel(model, bindingContext.ModelType, culture);
}
@@ -72,8 +83,7 @@ namespace Umbraco.Web.Mvc
if (modelType.Implements<IPublishedContent>())
{
if ((sourceContent.GetType().Inherits(modelType)) == false)
throw new ModelBindingException(string.Format("Cannot bind source content type {0} to model type {1}.",
sourceContent.GetType(), modelType));
ThrowModelBindingException(true, false, sourceContent.GetType(), modelType);
return sourceContent;
}
@@ -88,8 +98,7 @@ namespace Umbraco.Web.Mvc
{
var targetContentType = modelType.GetGenericArguments()[0];
if ((sourceContent.GetType().Inherits(targetContentType)) == false)
throw new ModelBindingException(string.Format("Cannot bind source content type {0} to model content type {1}.",
sourceContent.GetType(), targetContentType));
ThrowModelBindingException(true, true, sourceContent.GetType(), targetContentType);
return Activator.CreateInstance(modelType, sourceContent, culture);
}
}
@@ -99,10 +108,36 @@ namespace Umbraco.Web.Mvc
if (attempt2.Success) return attempt2.Result;
// fail
throw new ModelBindingException(string.Format("Cannot bind source type {0} to model type {1}.",
sourceType, modelType));
ThrowModelBindingException(false, false, sourceType, modelType);
return null;
}
private static void ThrowModelBindingException(bool sourceContent, bool modelContent, Type sourceType, Type modelType)
{
var msg = new StringBuilder();
msg.Append("Cannot bind source");
if (sourceContent) msg.Append(" content");
msg.Append(" type ");
msg.Append(sourceType.FullName);
msg.Append(" to model");
if (modelContent) msg.Append(" content");
msg.Append(" type");
if (sourceType.FullName == modelType.FullName)
{
msg.Append(". Same type name but different assemblies.");
}
else
{
msg.Append(" ");
msg.Append(modelType.FullName);
msg.Append(".");
}
throw new ModelBindingException(msg.ToString());
}
public IModelBinder GetBinder(Type modelType)
{
// can bind to RenderModel

View File

@@ -59,11 +59,11 @@ namespace Umbraco.Web.Mvc
{
if (_publishedContentRequest != null)
return _publishedContentRequest;
if (RouteData.DataTokens.ContainsKey("umbraco-doc-request") == false)
if (RouteData.DataTokens.ContainsKey(Core.Constants.Web.PublishedDocumentRequestDataToken) == false)
{
throw new InvalidOperationException("DataTokens must contain an 'umbraco-doc-request' key with a PublishedContentRequest object");
}
_publishedContentRequest = (PublishedContentRequest)RouteData.DataTokens["umbraco-doc-request"];
_publishedContentRequest = (PublishedContentRequest)RouteData.DataTokens[Core.Constants.Web.PublishedDocumentRequestDataToken];
return _publishedContentRequest;
}
}

View File

@@ -97,9 +97,9 @@ namespace Umbraco.Web.Mvc
internal void SetupRouteDataForRequest(RenderModel renderModel, RequestContext requestContext, PublishedContentRequest docRequest)
{
//put essential data into the data tokens, the 'umbraco' key is required to be there for the view engine
requestContext.RouteData.DataTokens.Add("umbraco", renderModel); //required for the RenderModelBinder and view engine
requestContext.RouteData.DataTokens.Add("umbraco-doc-request", docRequest); //required for RenderMvcController
requestContext.RouteData.DataTokens.Add("umbraco-context", UmbracoContext); //required for UmbracoTemplatePage
requestContext.RouteData.DataTokens.Add(Core.Constants.Web.UmbracoDataToken, renderModel); //required for the RenderModelBinder and view engine
requestContext.RouteData.DataTokens.Add(Core.Constants.Web.PublishedDocumentRequestDataToken, docRequest); //required for RenderMvcController
requestContext.RouteData.DataTokens.Add(Core.Constants.Web.UmbracoContextDataToken, UmbracoContext); //required for UmbracoTemplatePage
}
private void UpdateRouteDataForRequest(RenderModel renderModel, RequestContext requestContext)
@@ -107,7 +107,7 @@ namespace Umbraco.Web.Mvc
if (renderModel == null) throw new ArgumentNullException("renderModel");
if (requestContext == null) throw new ArgumentNullException("requestContext");
requestContext.RouteData.DataTokens["umbraco"] = renderModel;
requestContext.RouteData.DataTokens[Core.Constants.Web.UmbracoDataToken] = renderModel;
// the rest should not change -- it's only the published content that has changed
}
@@ -337,7 +337,7 @@ namespace Umbraco.Web.Mvc
}
//store the route definition
requestContext.RouteData.DataTokens["umbraco-route-def"] = def;
requestContext.RouteData.DataTokens[Umbraco.Core.Constants.Web.UmbracoRouteDefinitionDataToken] = def;
return def;
}

View File

@@ -93,7 +93,7 @@ namespace Umbraco.Web.Mvc
/// <returns></returns>
private bool ShouldFindView(ControllerContext controllerContext, bool isPartial)
{
var umbracoToken = controllerContext.GetDataTokenInViewContextHierarchy("umbraco");
var umbracoToken = controllerContext.GetDataTokenInViewContextHierarchy(Core.Constants.Web.UmbracoDataToken);
//first check if we're rendering a partial view for the back office, or surface controller, etc...
//anything that is not IUmbracoRenderModel as this should only pertain to Umbraco views.

View File

@@ -32,7 +32,7 @@ namespace Umbraco.Web.Mvc
public static object GetRequiredObject(this RouteValueDictionary items, string key)
{
if (key == null) throw new ArgumentNullException("key");
if (!items.Keys.Contains(key))
if (items.Keys.Contains(key) == false)
throw new ArgumentNullException("The " + key + " parameter was not found but is required");
return items[key];
}

View File

@@ -185,9 +185,9 @@ namespace Umbraco.Web.Mvc
while (currentContext != null)
{
var currentRouteData = currentContext.RouteData;
if (currentRouteData.DataTokens.ContainsKey("umbraco-route-def"))
if (currentRouteData.DataTokens.ContainsKey(Core.Constants.Web.UmbracoRouteDefinitionDataToken))
{
return Attempt.Succeed((RouteDefinition)currentRouteData.DataTokens["umbraco-route-def"]);
return Attempt.Succeed((RouteDefinition)currentRouteData.DataTokens[Core.Constants.Web.UmbracoRouteDefinitionDataToken]);
}
if (currentContext.IsChildAction)
{

View File

@@ -24,7 +24,7 @@ namespace Umbraco.Web.Mvc
return false;
//ensure there is an umbraco token set
var umbracoToken = request.RouteData.DataTokens["umbraco"];
var umbracoToken = request.RouteData.DataTokens[Core.Constants.Web.UmbracoDataToken];
if (umbracoToken == null || string.IsNullOrWhiteSpace(umbracoToken.ToString()))
return false;

View File

@@ -34,7 +34,7 @@ namespace Umbraco.Web.Mvc
ValidateRouteData(context.RouteData);
var routeDef = (RouteDefinition)context.RouteData.DataTokens["umbraco-route-def"];
var routeDef = (RouteDefinition)context.RouteData.DataTokens[Umbraco.Core.Constants.Web.UmbracoRouteDefinitionDataToken];
//Special case, if it is webforms but we're posting to an MVC surface controller, then we
// need to return the webforms result instead
@@ -91,7 +91,7 @@ namespace Umbraco.Web.Mvc
/// </summary>
private static void ValidateRouteData(RouteData routeData)
{
if (routeData.DataTokens.ContainsKey("umbraco-route-def") == false)
if (routeData.DataTokens.ContainsKey(Umbraco.Core.Constants.Web.UmbracoRouteDefinitionDataToken) == false)
{
throw new InvalidOperationException("Can only use " + typeof(UmbracoPageResult).Name +
" in the context of an Http POST when using a SurfaceController form");

View File

@@ -27,24 +27,13 @@ namespace Umbraco.Web.Mvc
get
{
//we should always try to return the context from the data tokens just in case its a custom context and not
//using the UmbracoContext.Current.
//we will fallback to the singleton if necessary.
if (ViewContext.RouteData.DataTokens.ContainsKey("umbraco-context"))
{
return (UmbracoContext)ViewContext.RouteData.DataTokens.GetRequiredObject("umbraco-context");
}
//next check if it is a child action and see if the parent has it set in data tokens
if (ViewContext.IsChildAction)
{
if (ViewContext.ParentActionViewContext.RouteData.DataTokens.ContainsKey("umbraco-context"))
{
return (UmbracoContext)ViewContext.ParentActionViewContext.RouteData.DataTokens.GetRequiredObject("umbraco-context");
}
}
//lastly, we will use the singleton, the only reason this should ever happen is is someone is rendering a page that inherits from this
//class and are rendering it outside of the normal Umbraco routing process. Very unlikely.
return UmbracoContext.Current;
//using the UmbracoContext.Current, we will fallback to the singleton if necessary.
var umbCtx = ViewContext.GetUmbracoContext()
//lastly, we will use the singleton, the only reason this should ever happen is is someone is rendering a page that inherits from this
//class and are rendering it outside of the normal Umbraco routing process. Very unlikely.
?? UmbracoContext.Current;
return umbCtx;
}
}
@@ -66,16 +55,16 @@ namespace Umbraco.Web.Mvc
//we should always try to return the object from the data tokens just in case its a custom object and not
//using the UmbracoContext.Current.
//we will fallback to the singleton if necessary.
if (ViewContext.RouteData.DataTokens.ContainsKey("umbraco-doc-request"))
if (ViewContext.RouteData.DataTokens.ContainsKey(Core.Constants.Web.PublishedDocumentRequestDataToken))
{
return (PublishedContentRequest)ViewContext.RouteData.DataTokens.GetRequiredObject("umbraco-doc-request");
return (PublishedContentRequest)ViewContext.RouteData.DataTokens.GetRequiredObject(Core.Constants.Web.PublishedDocumentRequestDataToken);
}
//next check if it is a child action and see if the parent has it set in data tokens
if (ViewContext.IsChildAction)
{
if (ViewContext.ParentActionViewContext.RouteData.DataTokens.ContainsKey("umbraco-doc-request"))
if (ViewContext.ParentActionViewContext.RouteData.DataTokens.ContainsKey(Core.Constants.Web.PublishedDocumentRequestDataToken))
{
return (PublishedContentRequest)ViewContext.ParentActionViewContext.RouteData.DataTokens.GetRequiredObject("umbraco-doc-request");
return (PublishedContentRequest)ViewContext.ParentActionViewContext.RouteData.DataTokens.GetRequiredObject(Core.Constants.Web.PublishedDocumentRequestDataToken);
}
}

View File

@@ -3,6 +3,8 @@ using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.Security;
using Umbraco.Core.Configuration;
using Umbraco.Core.Models;
using Umbraco.Web.Models;
using Umbraco.Web.Routing;
@@ -19,7 +21,8 @@ namespace Umbraco.Web.Mvc
if (found == null) return new NotFoundHandler();
umbracoContext.PublishedContentRequest = new PublishedContentRequest(
umbracoContext.CleanedUmbracoUrl, umbracoContext.RoutingContext)
umbracoContext.CleanedUmbracoUrl, umbracoContext.RoutingContext,
UmbracoConfig.For.UmbracoSettings().WebRouting, s => Roles.Provider.GetRolesForUser(s))
{
PublishedContent = found
};
@@ -31,11 +34,11 @@ namespace Umbraco.Web.Mvc
var renderModel = new RenderModel(umbracoContext.PublishedContentRequest.PublishedContent, umbracoContext.PublishedContentRequest.Culture);
//assigns the required tokens to the request
requestContext.RouteData.DataTokens.Add("umbraco", renderModel);
requestContext.RouteData.DataTokens.Add("umbraco-doc-request", umbracoContext.PublishedContentRequest);
requestContext.RouteData.DataTokens.Add("umbraco-context", umbracoContext);
requestContext.RouteData.DataTokens.Add(Core.Constants.Web.UmbracoDataToken, renderModel);
requestContext.RouteData.DataTokens.Add(Core.Constants.Web.PublishedDocumentRequestDataToken, umbracoContext.PublishedContentRequest);
requestContext.RouteData.DataTokens.Add(Core.Constants.Web.UmbracoContextDataToken, umbracoContext);
//this is used just for a flag that this is an umbraco custom route
requestContext.RouteData.DataTokens.Add("umbraco-custom-route", true);
requestContext.RouteData.DataTokens.Add(Core.Constants.Web.CustomRouteDataToken, true);
//Here we need to detect if a SurfaceController has posted
var formInfo = RenderRouteHandler.GetFormInfo(requestContext);
@@ -49,7 +52,7 @@ namespace Umbraco.Web.Mvc
};
//set the special data token to the current route definition
requestContext.RouteData.DataTokens["umbraco-route-def"] = def;
requestContext.RouteData.DataTokens[Umbraco.Core.Constants.Web.UmbracoRouteDefinitionDataToken] = def;
return RenderRouteHandler.HandlePostedValues(requestContext, formInfo);
}

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