You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ro...@apache.org on 2017/10/18 23:23:53 UTC
[sling-org-apache-sling-resource-editor] 37/50: SLING-4555 Resource
Editor: added JavaScript unit tests, smaller JavaScript refactorings,
fixed "multi delete" e2e test,
added spec reporter for Jasmine Karma unit tests
This is an automated email from the ASF dual-hosted git repository.
rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-resource-editor.git
commit 0cfb43027208e42488537316338fad731bca8f63
Author: Sandro Boehme <sb...@apache.org>
AuthorDate: Tue May 19 10:05:45 2015 +0000
SLING-4555 Resource Editor: added JavaScript unit tests, smaller JavaScript refactorings, fixed "multi delete" e2e test, added spec reporter for Jasmine Karma unit tests
git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1680224 13f79535-47bb-0310-9956-ffa450edef68
---
frontend/Gruntfile.js | 26 ++-
frontend/package.json | 1 +
.../js/tree/JSTreeAdapter.js | 18 +-
.../js/tree/TreeController.js | 17 +-
src/test/javascript/e2e/spec/e2e_spec.js | 2 +-
src/test/javascript/spec/resource_editor_spec.js | 247 ++++++++++++++++++++-
6 files changed, 272 insertions(+), 39 deletions(-)
diff --git a/frontend/Gruntfile.js b/frontend/Gruntfile.js
index cf3eb4a..49559d1 100644
--- a/frontend/Gruntfile.js
+++ b/frontend/Gruntfile.js
@@ -50,8 +50,10 @@ module.exports = function(grunt) {
},
karma : {
files:[
- staticContentFolder+'/js/**/*.js',
- '../src/test/javascript/**/*spec.js'],
+ staticContentFolder+'/generated/3rd_party/js/**/*.js',
+ staticContentFolder+'/js/**/*.js',
+ '../src/test/javascript/spec/*spec.js'
+ ],
tasks: ['karma:desktop_build']
}
@@ -102,27 +104,29 @@ module.exports = function(grunt) {
runnerPort: 9999,
singleRun: true,
browsers: ['Chrome', 'Firefox', 'PhantomJS'],
- plugins : ['karma-jasmine', 'karma-phantomjs-launcher', 'karma-chrome-launcher', 'karma-firefox-launcher', 'karma-ie-launcher'],
+ reporters: ["spec"],
+ specReporter: {maxLogLines: 5},
+ plugins : ['karma-jasmine', 'karma-phantomjs-launcher', 'karma-chrome-launcher', 'karma-firefox-launcher', 'karma-ie-launcher',
+ 'karma-spec-reporter'],
frameworks: ['jasmine'],
- files: ['../src/test/javascript/spec/*spec.js',
+ files: [
staticContentFolder+'/generated/3rd_party/js/jquery.min.js',
staticContentFolder+'/generated/3rd_party/js/**/*.js',
- staticContentFolder+'/js/**/*.js'
+ staticContentFolder+'/js/**/*.js',
+ '../src/test/javascript/spec/*spec.js'
]
},
desktop_build: {
singleRun: true,
browsers: ['Chrome', 'Firefox']
},
+ multi_run: {
+ singleRun: false,
+ browsers: ['Chrome', 'Firefox']
+ },
build: {
singleRun: true,
browsers: ['PhantomJS']
- },
- watch: {
- reporters: 'dots',
- autoWatch: true,
- background: true,
- singleRun: false
}
},
webdriver: {
diff --git a/frontend/package.json b/frontend/package.json
index eddceae..7fe4321 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -23,6 +23,7 @@
"grunt-contrib-watch": "0.6.1",
"grunt-karma": "0.10.1",
"karma-jasmine": "0.3.5",
+ "karma-spec-reporter": "0.0.19",
"karma-phantomjs-launcher": "~0.1.4",
"karma-chrome-launcher": "0.1.7",
"karma-firefox-launcher": "0.1.4",
diff --git a/src/main/resources/SLING-INF/libs/sling/resource-editor-static-content/js/tree/JSTreeAdapter.js b/src/main/resources/SLING-INF/libs/sling/resource-editor-static-content/js/tree/JSTreeAdapter.js
index b7338d4..bd0a09d 100644
--- a/src/main/resources/SLING-INF/libs/sling/resource-editor-static-content/js/tree/JSTreeAdapter.js
+++ b/src/main/resources/SLING-INF/libs/sling/resource-editor-static-content/js/tree/JSTreeAdapter.js
@@ -37,22 +37,14 @@ org.apache.sling.reseditor.JSTreeAdapter = (function() {
this.settings = settings;
this.treeController = treeController;
this.mainController = mainController;
-var pathSuffix = ".html";
-var pathEndsWithPathSuffix = settings.resourcePath.substring(settings.resourcePath.length-pathSuffix.length) == pathSuffix;
-var resourcePath = (pathEndsWithPathSuffix) ? settings.resourcePath.substring(0,settings.resourcePath.length-pathSuffix.length) : settings.resourcePath;
-var currentNodePath = this.mainController.encodeToHTML(resourcePath);
-var paths = currentNodePath.substring(1).split("/");
-var selectingNodeWhileOpeningTree=true;
-var thisJSTreeAdapter = this;
+ var thisJSTreeAdapter = this;
$(document).ready(function() {
$(window).resize( function() {
thisJSTreeAdapter.mainController.adjust_height();
});
- var selectorFromCurrentPath = treeController.getSelectorFromPath(currentNodePath);
-
var scrollToPathFinished=false;
thisJSTreeAdapter.mainController.adjust_height();
@@ -62,10 +54,12 @@ $(document).ready(function() {
// select the tree container using jQuery
$("#tree")
.bind("loaded.jstree", function (event, data) {
- if (currentNodePath != "/") {
- treeController.openElement($("#tree > ul > li[nodename=''] > ul"), paths);
+ var pathElements = treeController.getPathElements(settings.resourcePath);
+
+ if (pathElements.length >= 1 && pathElements[0] != "") {
+ treeController.openElement($("#tree > ul > li[nodename=''] > ul"), pathElements);
}
- selectingNodeWhileOpeningTree=false;
+
// position the info-icon
$('#tree-info-icon').show();
$('#root i:first').before($('#tree-info-icon'));
diff --git a/src/main/resources/SLING-INF/libs/sling/resource-editor-static-content/js/tree/TreeController.js b/src/main/resources/SLING-INF/libs/sling/resource-editor-static-content/js/tree/TreeController.js
index 9a90bf4..ab0f571 100644
--- a/src/main/resources/SLING-INF/libs/sling/resource-editor-static-content/js/tree/TreeController.js
+++ b/src/main/resources/SLING-INF/libs/sling/resource-editor-static-content/js/tree/TreeController.js
@@ -132,6 +132,14 @@ org.apache.sling.reseditor.TreeController = (function() {
}
}
+ TreeController.prototype.getPathElements = function(resourcePath){
+ var pathSuffix = ".html";
+ var pathEndsWithPathSuffix = resourcePath.substring(resourcePath.length-pathSuffix.length) == pathSuffix;
+ var resourcePathWithoutSuffix = (pathEndsWithPathSuffix) ? resourcePath.substring(0,resourcePath.length-pathSuffix.length) : resourcePath;
+ var currentNodePath = this.mainController.encodeToHTML(resourcePathWithoutSuffix);
+ return currentNodePath.substring(1).split("/");
+ }
+
TreeController.prototype.getSelectorFromPath = function(path){
var paths = path.substring(1).split("/");
return "#tree > ul [nodename='"+paths.join("'] > ul > [nodename='")+"']";
@@ -166,9 +174,7 @@ org.apache.sling.reseditor.TreeController = (function() {
if (paths.length>0){
thisTreeController.openElement($("#"+pathElementLi.attr('id')).children("ul"), paths);
} else {
- selectingNodeWhileOpeningTree=true;
- $('#tree').jstree('select_node', pathElementLi.attr('id'), 'true'/*doesn't seem to work*/);
- selectingNodeWhileOpeningTree=false;
+ $('#tree').jstree('select_node', pathElementLi.attr('id'), 'true');
var target = $('#'+pathElementLi.attr('id')+' a:first');
target.focus();
}
@@ -237,7 +243,7 @@ org.apache.sling.reseditor.TreeController = (function() {
var confirmationMsg = "You are about to delete '"+resourcePathToDelete+"' and all its sub nodes. Are you sure?";
var decodedResourcePath = this.mainController.decodeFromHTML(resourcePathToDelete);
var encodedResourcePathToDelete = this.mainController.encodeURL(decodedResourcePath);
- bootbox.confirm(confirmationMsg, function(result) {
+ var sendDeletePost = function(result) {
if (result){
$.ajax({
type: 'POST',
@@ -256,7 +262,8 @@ org.apache.sling.reseditor.TreeController = (function() {
}
});
}
- });
+ };
+ bootbox.confirm(confirmationMsg, sendDeletePost);
}
TreeController.prototype.openAddNodeDialog = function(li) {
diff --git a/src/test/javascript/e2e/spec/e2e_spec.js b/src/test/javascript/e2e/spec/e2e_spec.js
index fb9d379..9143602 100644
--- a/src/test/javascript/e2e/spec/e2e_spec.js
+++ b/src/test/javascript/e2e/spec/e2e_spec.js
@@ -168,7 +168,7 @@ describe('A user of the Apache Sling Resource Editor', function() {
client = client.url(homeURL);
client
.waitForExist('#last-element').click("#root li[nodename=\"aTestNode\"] i.add-icon")
- .waitForVisible('#addNodeDialog.add-node-finished').click('#addNodeDialog .btn.btn-primary.submit')
+ .waitForVisible('#addNodeDialog.add-node-finished', 1000).click('#addNodeDialog .btn.btn-primary.submit')
// The open node animation will take longer than 500ms thus setting 2000ms as max.
.waitForExist('#root li[nodename="aTestNode"].opened', 2000).elements('#root li[nodename="aTestNode"].opened li a .jstree-themeicon', function(err, res) {
client
diff --git a/src/test/javascript/spec/resource_editor_spec.js b/src/test/javascript/spec/resource_editor_spec.js
index f53a5f1..5b45c9a 100644
--- a/src/test/javascript/spec/resource_editor_spec.js
+++ b/src/test/javascript/spec/resource_editor_spec.js
@@ -18,18 +18,245 @@
*/
describe('The Resource Editor', function() {
+ MockNodeTypeManager = (function() {
+ function MockNodeTypeManager(settings, ntManager){
+ this.settings = settings;
+ this.ntManager = ntManager;
+ this.nodeTypesJson = {
+ "nt:unstructured": {
+ "declaredChildNodeDefinitions": [{
+ "name": "*",
+ "onParentVersion": "VERSION",
+ "allowsSameNameSiblings": true,
+ "defaultPrimaryType": "nt:unstructured"
+ }],
+ "declaredPropertyDefinitions": [
+ {
+ "name": "*",
+ "requiredType": "undefined",
+ "multiple": true
+ },
+ {
+ "name": "*",
+ "requiredType": "undefined"
+ }
+ ],
+ "orderableChildNodes": true
+ },
+ "nt:folder": {
+ "declaredChildNodeDefinitions": [{
+ "name": "*",
+ "onParentVersion": "VERSION",
+ "requiredPrimaryTypes": ["nt:hierarchyNode"]
+ }],
+ "declaredSupertypes": ["nt:hierarchyNode"]
+ },
+ "nt:hierarchyNode": {"declaredSupertypes": [
+ "mix:created",
+ "nt:base"
+ ]},
+ "nt:base": {
+ }
+ }
+ }
+
+ MockNodeTypeManager.prototype.getNodeTypeNames = function() {
+ return ["nt:unstructured", "nt:folder", "nt:hierarchyNode", "nt:base"];
+ }
+
+ MockNodeTypeManager.prototype.getNodeType = function(name) {
+ var nt = this.nodeTypesJson[name];
+ if (typeof nt.name === "undefined"){
+ nt.name = name;
+ nt.canAddProperty = function(propertyName, propertyType){
+ return true;
+ };
+ }
+ return nt;
+ }
+
+ return MockNodeTypeManager;
+ }());
+
+ var mockNtManager = new MockNodeTypeManager();
- it('\'s MainController', function() {
-// it('can encode a URL', function() {
- // Mock it!
-// var ntManager = new de.sandroboehme.NodeTypeManager();
- var mainControllerSettings = {
- contextPath: "/"//,
-// nodeTypes: ntManager.getNodeTypeNames()
- };
- var mainController = new org.apache.sling.reseditor.MainController(mainControllerSettings, null);
+ var mainControllerSettings = {
+ contextPath: "/",
+ nodeTypes: mockNtManager.getNodeTypeNames()
+ };
+
+ describe('\'s MainController', function() {
+ var mainController;
+
+ beforeEach(function() {
+ mainController = new org.apache.sling.reseditor.MainController(mainControllerSettings, mockNtManager);
+ });
+
+ it('can encode a URL', function() {
var urlToEncode = "/reseditor/testnode/$&?äöß<> test.html";
expect(mainController.encodeURL(urlToEncode)).toEqual("/reseditor/testnode/%24%26%3F%C3%A4%C3%B6%C3%9F%3C%3E%20test.html");
-// });
+ });
+
+ it('can encode HTML', function() {
+ expect(mainController.encodeToHTML("a<>b")).toEqual("a<>b");
+ });
+
+ it('can dencode HTML', function() {
+ expect(mainController.decodeFromHTML("a<>b")).toEqual("a<>b");
+ });
+
+ });
+
+ describe('\'s TreeController', function() {
+ var treeControllerSettings = {
+ contextPath: "/",
+ nodeTypes: mockNtManager.getNodeTypeNames()
+ };
+
+ var mainController;
+ var treeController;
+
+ beforeEach(function() {
+ mainController = new org.apache.sling.reseditor.MainController(mainControllerSettings, mockNtManager);
+ treeController = new org.apache.sling.reseditor.TreeController(treeControllerSettings, mainController);
+ });
+
+ it("can rename nodes", function() {
+ var htmlEncodedNewName = "newNodeName";
+ var data = {
+ text: htmlEncodedNewName,
+ old: "oldNodeName",
+ node: {id: "li_id"}
+ };
+ spyOn(treeController, "getPathFromLi").and.returnValue("/testnode/oldNodeName");
+ spyOn($, "ajax");
+ treeController.renameNode(null, data);
+
+ expect($.ajax.calls.mostRecent().args[0]["url"]).toEqual("/testnode/oldNodeName");
+ expect($.ajax.calls.mostRecent().args[0]["data"][":dest"]).toEqual("/testnode/newNodeName");
+ expect($.ajax.calls.mostRecent().args[0]["data"][":operation"]).toEqual("move");
+ expect($.ajax.calls.mostRecent().args[0]["data"]["_charset_"]).toEqual("utf-8");
+ });
+
+ it("can split the URL into path elements for deep links", function(){
+ var pathElements = treeController.getPathElements("/");
+ expect(pathElements.length).toBe(1);
+ expect(pathElements).toContain("");
+
+ pathElements = treeController.getPathElements("/testnodes");
+ expect(pathElements.length).toBe(1);
+ expect(pathElements).toContain("testnodes");
+
+ pathElements = treeController.getPathElements("/testnodes/level2/level3");
+ expect(pathElements.length).toBe(3);
+ expect(pathElements[0]).toBe("testnodes");
+ expect(pathElements[1]).toBe("level2");
+ expect(pathElements[2]).toBe("level3");
+
+ // Sometimes the path contains the ".html" suffix. Check that it still works
+ pathElements = treeController.getPathElements("/.html");
+ expect(pathElements.length).toBe(1);
+ expect(pathElements).toContain("");
+
+ pathElements = treeController.getPathElements("/testnodes.html");
+ expect(pathElements.length).toBe(1);
+ expect(pathElements).toContain("testnodes");
+
+ pathElements = treeController.getPathElements("/testnodes/level2/level3.html");
+ expect(pathElements.length).toBe(3);
+ expect(pathElements[0]).toBe("testnodes");
+ expect(pathElements[1]).toBe("level2");
+ expect(pathElements[2]).toBe("level3");
+ });
+
+ it("can delete nodes", function(){
+ spyOn(treeController, "getURLEncodedPathFromLi").and.returnValue("/testnode");
+ spyOn($.fn, "jstree").and.returnValue(["j1_18", "j1_20"]);
+ var getPathFromLiCount = 0;
+ spyOn(treeController,"getPathFromLi").and.callFake(function(){
+ getPathFromLiCount++;
+ switch(getPathFromLiCount) {
+ case 1:
+ return "/testnode/node1_to_delete";
+ case 2:
+ return "/testnode/node3_to_delete";
+ }
+ });
+
+ spyOn(bootbox, "confirm").and.callFake(function(){
+ var result = true;
+ /*
+ * The confirm dialog cannot be clicked in this test. We spy on this dialog, retrieve the function
+ * that gets called after the user clicked ok and then call this function to check our expectations.
+ */
+ // calling 'sendDeletePost()'
+ bootbox.confirm.calls.argsFor(0)[1](result);
+ });
+
+ spyOn($, "ajax");
+
+ treeController.deleteNodes({});
+
+ expect(treeController.getPathFromLi.calls.count()).toBe(2);
+
+ expect($.ajax.calls.mostRecent().args[0]["url"]).toEqual("/testnode");
+ expect($.ajax.calls.mostRecent().args[0]["data"][":operation"]).toEqual("delete");
+ expect($.ajax.calls.mostRecent().args[0]["data"]["_charset_"]).toEqual("utf-8");
+ expect($.ajax.calls.mostRecent().args[0]["data"][":applyTo"][0]).toEqual("/testnode/node1_to_delete");
+ expect($.ajax.calls.mostRecent().args[0]["data"][":applyTo"][1]).toEqual("/testnode/node3_to_delete");
+ });
+
+ it("can delete a single node", function(){
+ spyOn(treeController,"getPathFromLi").and.returnValue("/testnode/node2delete");
+
+ spyOn(bootbox, "confirm").and.callFake(function(){
+ var result = true;
+ /*
+ * The confirm dialog cannot be clicked in this test. We spy on this dialog, retrieve the function
+ * that gets called after the user clicked ok and then call this function to check our expectations.
+ */
+ // calling 'sendDeletePost()'
+ bootbox.confirm.calls.argsFor(0)[1](result);
+ });
+
+ spyOn($, "ajax");
+
+ treeController.deleteSingleNode({});
+
+ expect($.ajax.calls.mostRecent().args[0]["url"]).toEqual("/testnode/node2delete");
+ expect($.ajax.calls.mostRecent().args[0]["data"][":operation"]).toEqual("delete");
+ });
+ });
+
+ describe('\'s AddNodeController', function() {
+ var mainController;
+ var addNodeController;
+
+ beforeEach(function() {
+ mainController = new org.apache.sling.reseditor.MainController(mainControllerSettings, mockNtManager);
+ addNodeController = new org.apache.sling.reseditor.AddNodeController({}, mainController);
+ });
+
+ it("can add a node", function(){
+ spyOn(mainController, "encodeURL").and.returnValue("/testnode");
+
+ spyOn($.fn, "select2").and.returnValue("nt:unstructured");
+
+ spyOn($, 'ajax').and.callFake(function (req) {
+ var d = $.Deferred();
+ d.resolve({});
+ return d.promise();
+ });
+
+ spyOn(mainController,"redirectTo").and.returnValue(null);
+
+ addNodeController.addNode();
+
+ expect($.ajax.calls.mostRecent().args[0]["url"]).toEqual("/testnode");
+ expect($.ajax.calls.mostRecent().args[0]["data"]["_charset_"]).toEqual("utf-8");
+ expect($.ajax.calls.mostRecent().args[0]["data"]["jcr:primaryType"]).toEqual("nt:unstructured");
+ });
});
+
+
});
\ No newline at end of file
--
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.