diff --git a/src/Umbraco.Core/Services/Implement/MemberGroupService.cs b/src/Umbraco.Core/Services/Implement/MemberGroupService.cs index b07bb61dc1..c879a00ccb 100644 --- a/src/Umbraco.Core/Services/Implement/MemberGroupService.cs +++ b/src/Umbraco.Core/Services/Implement/MemberGroupService.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using Umbraco.Core.Events; using Umbraco.Core.Logging; @@ -79,6 +80,10 @@ namespace Umbraco.Core.Services.Implement public void Save(IMemberGroup memberGroup, bool raiseEvents = true) { + if (string.IsNullOrWhiteSpace(memberGroup.Name)) + { + throw new InvalidOperationException("The name of a MemberGroup can not be empty"); + } using (var scope = ScopeProvider.CreateScope()) { var saveEventArgs = new SaveEventArgs(memberGroup); diff --git a/src/Umbraco.Tests/Services/MemberGroupServiceTests.cs b/src/Umbraco.Tests/Services/MemberGroupServiceTests.cs new file mode 100644 index 0000000000..20205d74bc --- /dev/null +++ b/src/Umbraco.Tests/Services/MemberGroupServiceTests.cs @@ -0,0 +1,39 @@ +using System; +using System.Linq; +using NUnit.Framework; +using Umbraco.Core; +using Umbraco.Core.Models; +using Umbraco.Core.Models.Rdbms; +using Umbraco.Tests.TestHelpers; +using Umbraco.Tests.TestHelpers.Entities; + +namespace Umbraco.Tests.Services +{ + [DatabaseTestBehavior(DatabaseBehavior.NewDbFileAndSchemaPerTest)] + [TestFixture, RequiresSTA] + public class MemberGroupServiceTests : BaseServiceTest + { + [SetUp] + public override void Initialize() + { + base.Initialize(); + } + + [TearDown] + public override void TearDown() + { + base.TearDown(); + } + + [Test] + [ExpectedException("System.InvalidOperationException")] + public void New_MemberGroup_Is_Not_Allowed_With_Empty_Name() + { + var service = ServiceContext.MemberGroupService; + + service.Save(new MemberGroup {Name = ""}); + + Assert.Fail("An exception should have been thrown"); + } + } +} diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagecrop.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagecrop.directive.js index 73b74ead8b..5be2ec1173 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagecrop.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagecrop.directive.js @@ -103,34 +103,6 @@ angular.module("umbraco.directives") scope.dimensions.cropper.height = _viewPortH; // scope.dimensions.viewport.height - 2 * scope.dimensions.margin; }; - - //when loading an image without any crop info, we center and fit it - var resizeImageToEditor = function(){ - //returns size fitting the cropper - var size = cropperHelper.calculateAspectRatioFit( - scope.dimensions.image.width, - scope.dimensions.image.height, - scope.dimensions.cropper.width, - scope.dimensions.cropper.height, - true); - - //sets the image size and updates the scope - scope.dimensions.image.width = size.width; - scope.dimensions.image.height = size.height; - - //calculate the best suited ratios - scope.dimensions.scale.min = size.ratio; - scope.dimensions.scale.max = 2; - scope.dimensions.scale.current = size.ratio; - - //center the image - var position = cropperHelper.centerInsideViewPort(scope.dimensions.image, scope.dimensions.cropper); - scope.dimensions.top = position.top; - scope.dimensions.left = position.left; - - setConstraints(); - }; - //resize to a given ratio var resizeImageToScale = function(ratio){ //do stuff @@ -227,12 +199,19 @@ angular.module("umbraco.directives") //set dimensions on image, viewport, cropper etc setDimensions(image); - //if we have a crop already position the image - if(scope.crop){ - resizeImageToCrop(); - }else{ - resizeImageToEditor(); - } + //create a default crop if we haven't got one already + var createDefaultCrop = !scope.crop; + if (createDefaultCrop) { + calculateCropBox(); + } + + resizeImageToCrop(); + + //if we're creating a new crop, make sure to zoom out fully + if (createDefaultCrop) { + scope.dimensions.scale.current = scope.dimensions.scale.min; + resizeImageToScale(scope.dimensions.scale.min); + } //sets constaints for the cropper setConstraints(); diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagegravity.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagegravity.directive.js index 5732fa0eac..dfa58f34f8 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagegravity.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagegravity.directive.js @@ -28,7 +28,7 @@ /** Sets the css style for the Dot */ function style() { - if (vm.dimensions.width <= 0) { + if (vm.dimensions.width <= 0 || vm.dimensions.height <= 0) { //this initializes the dimensions since when the image element first loads //there will be zero dimensions setDimensions(); diff --git a/src/Umbraco.Web.UI.Client/src/common/services/cropperhelper.service.js b/src/Umbraco.Web.UI.Client/src/common/services/cropperhelper.service.js index e613ccad0d..256a1461db 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/cropperhelper.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/cropperhelper.service.js @@ -123,13 +123,6 @@ function cropperHelper(umbRequestHelper, $http) { return crop; }, - centerInsideViewPort : function(img, viewport){ - var left = viewport.width/ 2 - img.width / 2, - top = viewport.height / 2 - img.height / 2; - - return {left: left, top: top}; - }, - alignToCoordinates : function(image, center, viewport){ var min_left = (image.width) - (viewport.width); diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/boolean/boolean.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/boolean/boolean.controller.js index a6ef34f43b..df76c2d63a 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/boolean/boolean.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/boolean/boolean.controller.js @@ -1,4 +1,4 @@ -function booleanEditorController($scope) { +function booleanEditorController($scope, angularHelper) { function setupViewModel() { $scope.renderModel = { @@ -29,6 +29,7 @@ function booleanEditorController($scope) { // Update the value when the toggle is clicked $scope.toggle = function(){ + angularHelper.getCurrentForm($scope).$setDirty(); if($scope.renderModel.value){ $scope.model.value = "0"; setupViewModel();