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 <[email protected]>
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&lt;&gt;b");
+               });
+
+               it('can dencode HTML', function() {
+                       
expect(mainController.decodeFromHTML("a&lt;&gt;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
"[email protected]" <[email protected]>.

Reply via email to