more tests for block list editor

This commit is contained in:
Niels Lyngsø
2020-03-05 17:38:14 +01:00
parent 74165ae859
commit bc97861316
7 changed files with 101 additions and 47 deletions
@@ -313,6 +313,7 @@ angular.module('umbraco.mocks').
label: "Content",
id: 2,
properties: [
{ alias: "testproperty", label: "Test property", view: "textbox", value: "asdfghjk" },
{ alias: "valTest", label: "Validation test", view: "validationtest", value: "asdfasdf" },
{ alias: "bodyText", label: "Body Text", description: "Here you enter the primary article contents", view: "rte", value: "<p>askjdkasj lasjd</p>", config: {} },
{ alias: "textarea", label: "textarea", view: "textarea", value: "ajsdka sdjkds", config: { rows: 4 } },
@@ -2,10 +2,10 @@
"use strict";
angular
.module("umbraco")
.component("blockListPropertyEditorBlock", {
templateUrl: "views/propertyeditors/blocklist/blocklist.block.component.html",
.component("blockEditorBlock", {
templateUrl: "views/propertyeditors/blockeditor/blockeditor.block.component.html",
transclude: true,
controller: BlockListBlockController,
controller: BlockEditorBlockBlockController,
controllerAs: "vm",
bindings: {
block: "=",
@@ -16,7 +16,7 @@
}
});
function BlockListBlockController($scope, blockEditorService) {
function BlockEditorBlockBlockController($scope, blockEditorService) {
var unsubscribe = [];
var vm = this;
@@ -32,9 +32,10 @@
for (var p = 0; p < tab.properties.length; p++) {
var prop = tab.properties[p];
// Sadly we need to deep watch, cause its our only way to make sure that complex values gets synced. Alternative solution would be to sync on a broadcasted event, fired on Save and Copy eventually more.
// But to minimize the watch we only watch the value of properties. But because we are deep watching it means that we are watching everything of nested block editors, so this would only have a performance improvement for first levels of block editors.
// New thoughts, since the value of a property editors is just a pointer (if not primative) then we could properly live without deep watching? cause they reference the same?.. Lets investigate..
// Watch value of property since this is the only value we want to keep synced.
// Do notice that it is not performing a deep watch, meaning that we are only watching primatives and changes directly to the object of property-value.
// But we like to sync non-primative values as well! Yes, and this does happen, just not through this code, but through the nature of JavaScript.
// Non-primative values act as references to the same data and are therefor synced.
unsubscribe.push($scope.$watch("vm.block.content.variants[0].tabs["+t+"].properties["+p+"].value", createPropWatcher(prop)));
}
}
@@ -47,8 +48,6 @@
// sync data:
vm.block.contentModel[prop.alias] = prop.value;
//vm.blockEditorApi.sync();
// update label:
updateLabel();
}
@@ -58,20 +57,6 @@
function updateLabel() {
vm.block.label = blockEditorService.getBlockLabel(vm.block);
}
/**
* Listening for properties
*/
/*
function onBlockEditorValueUpdated($event) {
// Lets sync the value of the property that the event comes from, if we know that..
//$event.stopPropagation();
//$event.preventDefault();
};
unsubscribe.push($scope.$on("blockEditorValueUpdated", onBlockEditorValueUpdated));
*/
$scope.$on("$destroy", function () {
for (const subscription of unsubscribe) {
@@ -14,7 +14,7 @@
>
</button>
<block-list-property-editor-block block="blockItem" focus-this-block="vm.moveFocusToBlock === blockItem" block-editor-api="vm.blockEditorApi" show-copy="vm.showCopy" class="umb-block-list__block">
<block-editor-block block="blockItem" focus-this-block="vm.moveFocusToBlock === blockItem" block-editor-api="vm.blockEditorApi" show-copy="vm.showCopy" class="umb-block-list__block">
<div class="umb-block-list__block--content" ng-if="blockItem.view" ng-include="blockItem.view">
</div>
@@ -32,7 +32,7 @@
</span>
</button>
</div>
</block-list-property-editor-block>
</block-editor-block>
</div>
</div>
@@ -54,7 +54,7 @@
vm.model.value = vm.model.value || {};
modelObject = blockEditorService.createModelObject(vm.model.value, vm.model.editor, vm.model.config.blocks);
modelObject.loadScaffolding().then(loaded);
modelObject.loadScaffolding().then(onLoaded);
copyAllBlocksAction = {
labelKey: "clipboard_labelForCopyAllEntries",
@@ -90,7 +90,7 @@
}
}
function loaded() {
function onLoaded() {
vm.layout = modelObject.getLayout();
@@ -105,7 +105,7 @@
vm.availableContentTypes = modelObject.getAvailableAliasesForBlockContent();
vm.availableBlockTypes = modelObject.getAvailableBlocksForItemPicker();
$scope.$apply();
$scope.$evalAsync();
}
@@ -375,7 +375,7 @@
scroll: true,
start: function (ev, ui) {
runtimeSortVars.moveFromIndex = ui.item.index();
$scope.$apply(function () {
$scope.$evalAsync(function () {
vm.sorting = true;
});
},
@@ -394,7 +394,7 @@
vm.layout.splice(moveToIndex, 0, movedEntry);
}
$scope.$apply(function () {
$scope.$evalAsync(function () {
vm.sorting = false;
});
}
@@ -16,25 +16,25 @@
position: relative;
width: 100%;
.umb-block-list__block--head {
/*.umb-block-list__block--head {
opacity: 0;
transition: opacity 120ms;
}
.umb-block-list__block--actions {
}*/
> ng-transclude > .umb-block-list__block--actions {
opacity: 0;
transition: opacity 120ms;
}
&:hover, &:focus, &:focus-within {
.umb-block-list__block--head {
/*.umb-block-list__block--head {
opacity: 1;
}
}*/
.umb-block-list__block--actions {
> ng-transclude > .umb-block-list__block--actions {
opacity: 1;
}
}
/*
&:focus, &:focus-within {
.umb-block-list__block--head {
&::before {
@@ -42,8 +42,9 @@
}
}
}
*/
}
/*
.umb-block-list__block--head {
position: absolute;
top: 0;
@@ -77,7 +78,7 @@
label.umb-block-list__block--head {
cursor: grab;
}
*/
.umb-block-list__block--actions {
position: absolute;
top: 10px;
@@ -1,15 +1,19 @@
describe('blockEditorService tests', function () {
var blockEditorService, contentResource;
var blockEditorService, contentResource, $rootScope, $componentController;
beforeEach(module('umbraco.services'));
beforeEach(module('umbraco.resources'));
beforeEach(module('umbraco.mocks'));
beforeEach(module('umbraco'));
beforeEach(inject(function ($injector, mocksUtils) {
beforeEach(inject(function ($injector, mocksUtils, _$rootScope_, _$componentController_) {
mocksUtils.disableAuth();
$rootScope = _$rootScope_;
$componentController = _$componentController_;
contentResource = $injector.get("contentResource");
spyOn(contentResource, "getScaffold").and.callFake(
function () {
@@ -36,7 +40,7 @@
{
udi: 1234,
contentTypeAlias: "testAlias",
testvalue: "myTestValue"
testproperty: "myTestValue"
}
]
};
@@ -75,7 +79,7 @@
});
it('getLayoutEntry has right values', function (done) {
it('getLayoutEntry has values', function (done) {
var modelObject = blockEditorService.createModelObject(propertyModelMock, "Umbraco.TestBlockEditor", [blockConfigurationMock]);
@@ -94,7 +98,7 @@
});
it('getBlockModel provide value', function (done) {
it('getBlockModel has values', function (done) {
var modelObject = blockEditorService.createModelObject(propertyModelMock, "Umbraco.TestBlockEditor", [blockConfigurationMock]);
@@ -102,13 +106,76 @@
modelObject.loadScaffolding().then(() => {
var layout = modelObject.getLayout();
expect(layout).not.toBeUndefined();
var blockModel = modelObject.getBlockModel(layout[0]);
expect(blockModel).not.toBeUndefined();
expect(blockModel[0].udi).toBe(propertyModelMock.data[0].udi);
expect(blockModel[0].testvalue).toBe(propertyModelMock.data[0].testvalue);
expect(blockModel.contentModel.udi).toBe(propertyModelMock.data[0].udi);
expect(blockModel.content.variants[0].tabs[0].properties[0].value).toBe(propertyModelMock.data[0].testproperty);
done();
});
});
it('getBlockModel syncs primative values', function (done) {
var propertyModel = angular.copy(propertyModelMock);
var modelObject = blockEditorService.createModelObject(propertyModel, "Umbraco.TestBlockEditor", [blockConfigurationMock]);
modelObject.loadScaffolding().then(() => {
var layout = modelObject.getLayout();
var blockModel = modelObject.getBlockModel(layout[0]);
blockEditorBlockComponenet = $componentController("blockEditorBlock", null, {"block": blockModel, "blockEditorApi": {}, "class": "testClass"});
blockEditorBlockComponenet.$onInit();
blockModel.content.variants[0].tabs[0].properties[0].value = "anotherTestValue";
$rootScope.$digest();// invoke angularJS Store.
expect(blockModel.contentModel).toBe(propertyModel.data[0]);
expect(blockModel.contentModel.testproperty).toBe("anotherTestValue");
expect(propertyModel.data[0].testproperty).toBe("anotherTestValue");
//
done();
});
});
it('getBlockModel syncs values of object', function (done) {
var propertyModel = angular.copy(propertyModelMock);
var complexValue = {"list": ["A", "B", "C"]};
propertyModel.data[0].testproperty = complexValue;
var modelObject = blockEditorService.createModelObject(propertyModel, "Umbraco.TestBlockEditor", [blockConfigurationMock]);
modelObject.loadScaffolding().then(() => {
var layout = modelObject.getLayout();
var blockModel = modelObject.getBlockModel(layout[0]);
blockEditorBlockComponenet = $componentController("blockEditorBlock", null, {"block": blockModel, "blockEditorApi": {}, "class": "testClass"});
blockEditorBlockComponenet.$onInit();
blockModel.content.variants[0].tabs[0].properties[0].value.list[0] = "AA";
blockModel.content.variants[0].tabs[0].properties[0].value.list.push("D");
$rootScope.$digest();// invoke angularJS Store.
expect(propertyModel.data[0].testproperty.list[0]).toBe("AA");
expect(propertyModel.data[0].testproperty.list.length).toBe(4);
done();
});