You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by sb...@apache.org on 2015/05/19 12:05:46 UTC
svn commit: r1680224 - in /sling/trunk/contrib/explorers/resourceeditor:
frontend/
src/main/resources/SLING-INF/libs/sling/resource-editor-static-content/js/tree/
src/test/javascript/e2e/spec/ src/test/javascript/spec/
Author: sboehme
Date: Tue May 19 10:05:45 2015
New Revision: 1680224
URL: http://svn.apache.org/r1680224
Log:
SLING-4555 Resource Editor: added JavaScript unit tests, smaller JavaScript refactorings, fixed "multi delete" e2e test, added spec reporter for Jasmine Karma unit tests
Modified:
sling/trunk/contrib/explorers/resourceeditor/frontend/Gruntfile.js
sling/trunk/contrib/explorers/resourceeditor/frontend/package.json
sling/trunk/contrib/explorers/resourceeditor/src/main/resources/SLING-INF/libs/sling/resource-editor-static-content/js/tree/JSTreeAdapter.js
sling/trunk/contrib/explorers/resourceeditor/src/main/resources/SLING-INF/libs/sling/resource-editor-static-content/js/tree/TreeController.js
sling/trunk/contrib/explorers/resourceeditor/src/test/javascript/e2e/spec/e2e_spec.js
sling/trunk/contrib/explorers/resourceeditor/src/test/javascript/spec/resource_editor_spec.js
Modified: sling/trunk/contrib/explorers/resourceeditor/frontend/Gruntfile.js
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/explorers/resourceeditor/frontend/Gruntfile.js?rev=1680224&r1=1680223&r2=1680224&view=diff
==============================================================================
--- sling/trunk/contrib/explorers/resourceeditor/frontend/Gruntfile.js (original)
+++ sling/trunk/contrib/explorers/resourceeditor/frontend/Gruntfile.js Tue May 19 10:05:45 2015
@@ -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: {
Modified: sling/trunk/contrib/explorers/resourceeditor/frontend/package.json
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/explorers/resourceeditor/frontend/package.json?rev=1680224&r1=1680223&r2=1680224&view=diff
==============================================================================
--- sling/trunk/contrib/explorers/resourceeditor/frontend/package.json (original)
+++ sling/trunk/contrib/explorers/resourceeditor/frontend/package.json Tue May 19 10:05:45 2015
@@ -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",
Modified: sling/trunk/contrib/explorers/resourceeditor/src/main/resources/SLING-INF/libs/sling/resource-editor-static-content/js/tree/JSTreeAdapter.js
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/explorers/resourceeditor/src/main/resources/SLING-INF/libs/sling/resource-editor-static-content/js/tree/JSTreeAdapter.js?rev=1680224&r1=1680223&r2=1680224&view=diff
==============================================================================
--- sling/trunk/contrib/explorers/resourceeditor/src/main/resources/SLING-INF/libs/sling/resource-editor-static-content/js/tree/JSTreeAdapter.js (original)
+++ sling/trunk/contrib/explorers/resourceeditor/src/main/resources/SLING-INF/libs/sling/resource-editor-static-content/js/tree/JSTreeAdapter.js Tue May 19 10:05:45 2015
@@ -37,22 +37,14 @@ org.apache.sling.reseditor.JSTreeAdapter
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'));
Modified: sling/trunk/contrib/explorers/resourceeditor/src/main/resources/SLING-INF/libs/sling/resource-editor-static-content/js/tree/TreeController.js
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/explorers/resourceeditor/src/main/resources/SLING-INF/libs/sling/resource-editor-static-content/js/tree/TreeController.js?rev=1680224&r1=1680223&r2=1680224&view=diff
==============================================================================
--- sling/trunk/contrib/explorers/resourceeditor/src/main/resources/SLING-INF/libs/sling/resource-editor-static-content/js/tree/TreeController.js (original)
+++ sling/trunk/contrib/explorers/resourceeditor/src/main/resources/SLING-INF/libs/sling/resource-editor-static-content/js/tree/TreeController.js Tue May 19 10:05:45 2015
@@ -132,6 +132,14 @@ org.apache.sling.reseditor.TreeControlle
}
}
+ 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.TreeControlle
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.TreeControlle
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.TreeControlle
}
});
}
- });
+ };
+ bootbox.confirm(confirmationMsg, sendDeletePost);
}
TreeController.prototype.openAddNodeDialog = function(li) {
Modified: sling/trunk/contrib/explorers/resourceeditor/src/test/javascript/e2e/spec/e2e_spec.js
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/explorers/resourceeditor/src/test/javascript/e2e/spec/e2e_spec.js?rev=1680224&r1=1680223&r2=1680224&view=diff
==============================================================================
--- sling/trunk/contrib/explorers/resourceeditor/src/test/javascript/e2e/spec/e2e_spec.js (original)
+++ sling/trunk/contrib/explorers/resourceeditor/src/test/javascript/e2e/spec/e2e_spec.js Tue May 19 10:05:45 2015
@@ -168,7 +168,7 @@ describe('A user of the Apache Sling Res
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
Modified: sling/trunk/contrib/explorers/resourceeditor/src/test/javascript/spec/resource_editor_spec.js
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/explorers/resourceeditor/src/test/javascript/spec/resource_editor_spec.js?rev=1680224&r1=1680223&r2=1680224&view=diff
==============================================================================
--- sling/trunk/contrib/explorers/resourceeditor/src/test/javascript/spec/resource_editor_spec.js (original)
+++ sling/trunk/contrib/explorers/resourceeditor/src/test/javascript/spec/resource_editor_spec.js Tue May 19 10:05:45 2015
@@ -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