<commit_before>define(['/common/LogManager.js','/common/EventDispatcher.js', './../../common/CommonUtil.js', '/socket.io/socket.io.js'],function(LogManager, EventDispatcher, commonUtil){
    var logger,
        Client,
        CommandQueue,
        LocalCommander,
        Storage,
        ClientNode,
        ClientNode2,
        Territory;

    logger = LogManager.create("Client");

    Client = function(server){
        var socket = io.connect(server),
            connected = false,
            storage = new Storage(),
            self = this,
            clipboard = {},
            updateStorage,
            updateUsers,
            users ={},
            shootEvent,
            handleMessage,
            selectedObjectId = null;

        /*event functions to relay information between users*/
        $.extend(this, new EventDispatcher());

        this.events = {
            "SELECTEDOBJECT_CHANGED" : "SELECTEDOBJECT_CHANGED"
        };
        this.setSelectedObjectId = function ( objectId ) {
            if ( objectId !== selectedObjectId ) {
                selectedObjectId = objectId;

                self.dispatchEvent( self.events.SELECTEDOBJECT_CHANGED, selectedObjectId );
            }
        };

        /*socket functions*/
        socket.on('connect',function(msg){
            connected = true;
        });
        socket.on('reconnecting',function(msg){
            connected = false;
        });
        socket.on('serverMessage',function(msg){
            socket.emit('serverMessageAck');
            handleMessage(msg);
        });
        socket.on('clientMessageAck',function(msg){

        });
        socket.on('clientMessageNack',function(msg){

        });

        /*MGA like functions*/
        this.setAttributes = function(id,name,value){
            var data,
                attributes,
                command;

            data = storage.get(id);
            if(data){
                attributes = commonUtil.copy(data.attributes);
                attributes[name] = value;
                self.sendMessage({transactionId:"talan ezt majd hasznaljuk",commands:[{type:"modify",id:id,attributes:attributes}]});
            }
        };
        this.setRegistry = function(id,name,value){
            var data,
                registry,
                command;

            data = storage.get(id);
            if(data){
                registry = commonUtil.copy(data.registry);
                registry[name] = value;
                self.sendMessage({transactionId:"talan ezt majd hasznaljuk",commands:[{type:"modify",id:id,registry:registry}]});
            }
        };
        this.copyNodes = function(ids){
            clipboard = ids;
            self.sendMessage({transactionId:"talan ezt majd hasznaljuk",commands:[{type:"copy",ids:clipboard}]});
        };
        this.pasteNodes = function(id){
            self.sendMessage({transactionId:"talan ezt majd hasznaljuk",commands:[{type:"paste",id:id}]});
        };
        this.deleteNode = function(id){
            self.sendMessage({transactionId:"talan ezt majd hasznaljuk",commands:[{type:"delete",id:id}]});
        };
        this.delMoreNodes = function(ids){
            var i;
            for(i=0;i<ids.length;i++){
                self.deleteNode(ids[i]);
            }
        };
        this.createChild = function(parameters){
            var commands=[],
                guid,
                baseId,
                parent,
                attributes;
            if(parameters.parentId){
                baseId = parameters.baseId || "object";
                //guid = commonUtil.guid();
                //TODO: readable ID for the testing should be removed at some point
                parent = storage.get(parameters.parentId);
                if(parent){
                    guid = "child_"+parameters.parentId+"_"+parent.relations.childrenIds.length;
                }
                else{
                    guid = "child_"+parameters.parentId+"_N";
                }
                attributes = {name:guid};
                commands.push({type:"createChild",baseId:baseId,parentId:parameters.parentId,newguid:guid});
                commands.push({type:"modify",id:guid,attributes:attributes});
                self.sendMessage({transactionId:"talan ezt majd hasznaljuk",commands:commands});
            }
            else{
                logger.error("fraudulent child creation: "+JSON.stringify(parameters));
            }
            self.sendMessage({transactionId:"talan ezt majd hasznaljuk",commands:[{type:"createChild",baseId:base,parentId:parent}]});
        };
        this.createSubType = function(parent,base){
            self.sendMessage({transactionId:"talan ezt majd hasznaljuk",commands:[{type:"createSubType",baseId:base,parentId:parent}]});
        };
        this.makePointer = function(id,name,to){
            self.sendMessage({transactionId:"talan ezt majd hasznaljuk",commands:[{type:"point",id:id,to:to,name:name}]});
        };
        this.delPointer = function(id,name){
            self.sendMessage({transactionId:"talan ezt majd hasznaljuk",commands:[{type:"point",id:id,to:null,name:name}]});
        };
        this.makeConnection = function(parameters){
            var commands=[],
                baseId,
                attributes,
                guid;
            if(parameters.parentId && parameters.sourceId && parameters.targetId){
                baseId = parameters.baseId || "connection";
                //guid = commonUtil.guid();
                //TODO: just to make recognisable ID for connection.... delete at some point please
                guid = "conn_" + parameters.sourceId + "_" + parameters.targetId;
                attributes = {name:guid};
                commands.push({type:"createChild",baseId:baseId,parentId:parameters.parentId,newguid:guid});
                commands.push({type:"point",id:guid,name:"source",to:parameters.sourceId});
                commands.push({type:"point",id:guid,name:"target",to:parameters.targetId});
                attributes.directed = parameters.directed;
                commands.push({type:"modify",id:guid,attributes:attributes});
                self.sendMessage({transactionId:"talan ezt majd hasznaljuk",commands:commands});
            }
            else{
                logger.error("fraudulent connection creation: "+JSON.stringify(parameters));
            }
        };

        /*UserInterface handling*/
        this.addUI = function(ui){
            var guid;
            guid = commonUtil.guid();
            users[guid] = new User(self,ui,storage);
            return guid;
        };
        this.removeUI = function(guid){
            delete users[guid];
        };
        this.updateTerritory = function(guid,patterns){
            if(users[guid]){
                users[guid].updatePatterns(patterns);
                self.sendMessage({transactionId:"talan ezt majd hasznaljuk",commands:[{type:"territory",id:guid,patterns:users[guid].getPatterns()}]});
            }
        };

        /*getting a node*/
        this.getNode = function(id){
            if(storage.get(id)){
                return new ClientNode(self,id,storage);
            }
            else{
                return storage.get(id);
            }
        };

        /*socket like functions*/
        this.sendMessage = function(msg){
            socket.emit('clientMessage',msg);
        };
        /*private functions*/
        shootEvent = function(type,id){
            var i,
                data;
            data = storage.get(id);
            for(i in users){
                users[i].shootEvent(id,type);
            }

            if(data && type === "modify"){
                if(data.relations.inheritorIds){
                    for(i=0;i<data.relations.inheritorIds.length;i++){
                        shootEvent(type,data.relations.inheritorIds[i]);
                    }
                }
            }
        };
        handleMessage = function(msg){
            var i;

            /*main*/
            /*if the transaction failed, there is nothing to do*/
            /*for(i=0;i<msg.length;i++){
                if(msg[i].type === "command"){
                    commandqueue.commandResult(msg[i].cid,msg[i].success);
                    if(msg[i].success === "false"){
                        return;
                    }
                }
            }*/

            /*first we shoot the unload events*/
            for(i=0;i<msg.length;i++){
                if(msg[i].type === "unload"){
                    shootEvent("unload",msg[i].id);
                }
            }
            /*then we update the storage*/
            for(i=0;i<msg.length;i++){
                if(msg[i].type !== "command"){
                    storage.set(msg[i].id,msg[i].object);
                }
            }
            /*then we update the users*/
            for(i in users){
                users[i].updateTerritory();
            }
            /*then we shoot all other events*/
            for(i=0;i<msg.length;i++){
                if(msg[i].type === "load" || msg[i].type === "update" || msg[i].type === "create" || msg[i].type === "delete"){
                    shootEvent(msg[i].type,msg[i].id);
                }
            }
        };
    };
    User = function(client,ui,storage){
        var patterns = {},
            ids=[];

        /*public functions*/
        this.getPatterns = function(){
            return patterns;
        };
        this.updatePatterns = function(newpatterns){
            patterns = newpatterns;
        };
        this.shootEvent = function(id,type){
            if(ids.indexOf(id)!== -1){
                ui.onEvent(type,id);
            }
        };
        this.updateTerritory = function(){
            var i,
                updatePattern,
                updateRule;

            updateRule = function(id,rulename,rulevalue,itemssofar){
                var i,
                    data = storage.get(id);

                if(data === null || data === undefined){
                    return;
                }

                if(commonUtil.insertIntoArray(itemssofar,id)){
                    if(rulename === "pointer"){
                        if(rulevalue.value === 0){
                            return;
                        }
                        if(data.pointers[rulevalue.name]){
                            if(data.pointers[rulevalue.name].to){
                                updateRule(data.pointers[rulevalue.name].to,rulename,{name:rulevalue.name,value:rulevalue.value-1},itemssofar);
                            }
                        }
                        return;
                    }
                    else{
                        if(rulevalue === 0){
                            return;
                        }
                        switch(rulename){
                            case "parent":
                                if(data.relations.parentId){
                                    updateRule(data.relations.parentId,rulename,rulevalue-1,itemssofar);
                                }
                                break;
                            case "children":
                                if(data.relations.childrenIds){
                                    for(i=0;i<data.relations.childrenIds.length;i++){
                                        updateRule(data.relations.childrenIds[i],rulename,rulevalue-1,itemssofar);
                                    }
                                }
                                break;
                            case "inheritor":
                                if(data.relations.inheritorIds){
                                    for(i=0;i<data.relations.inheritorIds.length;i++){
                                        updateRule(data.relations.inheritorIds[i],rulename,rulevalue-1,itemssofar);
                                    }
                                }
                                break;
                        }
                    }
                }
                else{
                    return; /*we found a loop*/
                }
            };
            updatePattern = function(id,pattern){
                var i,
                    rulechain;
                for(i in pattern){
                    rulechain = [];
                    updateRule(id,i,commonUtil.copy(pattern[i]),rulechain);
                    ids = commonUtil.mergeArrays(ids,rulechain);
                }
            };
            /*main*/
            ids = [];
            for(i in patterns){
                updatePattern(i,patterns[i]);
            }
        };
    };
    CommandQueue = function(client,storage){
        var queue = {},
            sent = {},
            timer = 10000;
            cansend = true;

        /*public functions*/
        this.push = function(command){
            if(command.type === "territory"){
                /*these can go paralelly without cid*/
                client.sendMessage({commands:[command]});
                return;
            }
            queue[command.cid] = command;
            setTimeout(function(){
                commandTimeout(command.cid);
            },timer);
            sendNextClientMessage();
        };
        this.commandResult = function(cid,success){
            /*TODO success*/
            delete sent[cid];

            if(isSentEmpty()){
                cansend = true;
                sendNextClientMessage();
            }
        };
        var isSentEmpty = function(){
            var counter = 0;
            for(var i in sent){
                counter++;
            }
            if(counter === 0){
                return true;
            }
            return false;
        };
        var sendNextClientMessage = function(){
            logger.debug("trying to send next command message to server (cansend="+cansend+",sentisempty="+isSentEmpty());
            if(cansend ===true || isSentEmpty()){
                cansend = true;
                var msg = {commands:[]};
                for(var i in queue){
                    msg.commands.push(queue[i]);
                }
                logger.debug("next command message to server "+JSON.stringify(msg));
                if(msg.commands.length>0){
                    client.sendMessage(msg);
                    cansend = false;
                    sent = queue;
                    queue = {};
                }
            }
        };
        var commandTimeout = function(cid){
            if(queue[cid] || sent[cid]){
                console.log("command timeout "+cid);
            }
            delete queue[cid];
            delete sent[cid];

            if(isSentEmpty()){
                cansend = true;
                sendNextClientMessage();
            }
        };
    };
    Storage = function(client){
        var objects = {};

        /*public functions*/
        this.get = function(id){
            logger.debug("Storage.get "+id);
            return objects[id];
        };
        this.set = function(id,object){
            logger.debug("Storage.set "+id+","+JSON.stringify(object));
            objects[id] = object;
        };
    };
    ClientNode = function(client,id,storage){
        var selfdata = storage.get(id),
            rGetAttribute,
            rGetRegistry;
        /*public funcitons*/
        this.isDeleted = function(){
            return selfdata === null;
        };
        this.getParentId = function(){
            if(selfdata){
                return selfdata.relations.parentId;
            }
            else{
                return selfdata;
            }
        };
        this.getId = function(){
            if(selfdata){
                return selfdata._id;
            }
            else{
                return selfdata;
            }
        };
        this.getChildrenIds = function(){
            if(selfdata){
                return selfdata.relations.childrenIds;
            }
            else{
                return selfdata;
            }
        };
        this.getBaseId = function(){
            if(selfdata){
                return selfdata.relations.baseId;
            }
            else{
                return selfdata;
            }
        };
        this.getInheritorIds = function(){
            if(selfdata){
                return selfdata.relations.inheritorIds;
            }
            else{
                return selfdata
            }
        };
        this.getAttribute = function(name){
            if(selfdata){
                return rGetAttribute(id,name);
            }
            else{
                return selfdata;
            }
        };
        this.getRegistry = function(name){
            if(selfdata){
                return rGetRegistry(id,name);
            }
            else{
                return selfdata;
            }
        };
        this.getPointer = function(name){
            var pointer = {to:null,from:[]};
            if(selfdata.pointers[name]){
                pointer = commonUtil.copy(selfdata.pointers[name]);
            }
            return pointer;
        };
        this.getConnectionList = function(){
            var i,
                connectionlist = [],
                templist;
            if(selfdata === null || selfdata === undefined){
                return connectionlist;
            }
            if(selfdata.pointers.source){
                templist = commonUtil.copy(selfdata.pointers.source.from);
                for(i=0;i<templist.length;i++){
                    connectionlist.push({id:templist[i],out:true});
                }
            }
            if(selfdata.pointers.target){
                templist = commonUtil.copy(selfdata.pointers.target.from);
                for(i=0;i<templist.length;i++){
                    connectionlist.push({id:templist[i],out:false});
                }
            }
            return connectionlist;
        };
        /*private functions*/
        rGetAttribute = function(id,name){
            var data;
            data = storage.get(id);
            if(data){
                if(data.attributes[name]){
                    return data.attributes[name];
                }
                else{
                    if(data.relations.baseId){
                        return rGetAttribute(data.relations.baseId,name);
                    }
                    else{
                        return null;
                    }
                }
            }
            else{
                return data;
            }
        };
        rGetRegistry = function(id,name){
            var data;
            data = storage.get(id);
            if(data){
                if(data.registry[name]){
                    return data.registry[name];
                }
                else{
                    if(data.relations.baseId){
                        return rGetRegistry(data.relations.baseId,name);
                    }
                    else{
                        return null;
                    }
                }
            }
            else{
                return data;
            }

        };
    };
    return Client;
});
<commit_msg>fix getAttribute and getRegistry recursive value discovery<commit_after>define(['/common/LogManager.js','/common/EventDispatcher.js', './../../common/CommonUtil.js', '/socket.io/socket.io.js'],function(LogManager, EventDispatcher, commonUtil){
    var logger,
        Client,
        CommandQueue,
        LocalCommander,
        Storage,
        ClientNode,
        ClientNode2,
        Territory;

    logger = LogManager.create("Client");

    Client = function(server){
        var socket = io.connect(server),
            connected = false,
            storage = new Storage(),
            self = this,
            clipboard = {},
            updateStorage,
            updateUsers,
            users ={},
            shootEvent,
            handleMessage,
            selectedObjectId = null;

        /*event functions to relay information between users*/
        $.extend(this, new EventDispatcher());

        this.events = {
            "SELECTEDOBJECT_CHANGED" : "SELECTEDOBJECT_CHANGED"
        };
        this.setSelectedObjectId = function ( objectId ) {
            if ( objectId !== selectedObjectId ) {
                selectedObjectId = objectId;

                self.dispatchEvent( self.events.SELECTEDOBJECT_CHANGED, selectedObjectId );
            }
        };

        /*socket functions*/
        socket.on('connect',function(msg){
            connected = true;
        });
        socket.on('reconnecting',function(msg){
            connected = false;
        });
        socket.on('serverMessage',function(msg){
            socket.emit('serverMessageAck');
            handleMessage(msg);
        });
        socket.on('clientMessageAck',function(msg){

        });
        socket.on('clientMessageNack',function(msg){

        });

        /*MGA like functions*/
        this.setAttributes = function(id,name,value){
            var data,
                attributes,
                command;

            data = storage.get(id);
            if(data){
                attributes = commonUtil.copy(data.attributes);
                attributes[name] = value;
                self.sendMessage({transactionId:"talan ezt majd hasznaljuk",commands:[{type:"modify",id:id,attributes:attributes}]});
            }
        };
        this.setRegistry = function(id,name,value){
            var data,
                registry,
                command;

            data = storage.get(id);
            if(data){
                registry = commonUtil.copy(data.registry);
                registry[name] = value;
                self.sendMessage({transactionId:"talan ezt majd hasznaljuk",commands:[{type:"modify",id:id,registry:registry}]});
            }
        };
        this.copyNodes = function(ids){
            clipboard = ids;
            self.sendMessage({transactionId:"talan ezt majd hasznaljuk",commands:[{type:"copy",ids:clipboard}]});
        };
        this.pasteNodes = function(id){
            self.sendMessage({transactionId:"talan ezt majd hasznaljuk",commands:[{type:"paste",id:id}]});
        };
        this.deleteNode = function(id){
            self.sendMessage({transactionId:"talan ezt majd hasznaljuk",commands:[{type:"delete",id:id}]});
        };
        this.delMoreNodes = function(ids){
            var i;
            for(i=0;i<ids.length;i++){
                self.deleteNode(ids[i]);
            }
        };
        this.createChild = function(parameters){
            var commands=[],
                guid,
                baseId,
                parent,
                attributes;
            if(parameters.parentId){
                baseId = parameters.baseId || "object";
                //guid = commonUtil.guid();
                //TODO: readable ID for the testing should be removed at some point
                parent = storage.get(parameters.parentId);
                if(parent){
                    guid = "child_"+parameters.parentId+"_"+parent.relations.childrenIds.length;
                }
                else{
                    guid = "child_"+parameters.parentId+"_N";
                }
                attributes = {name:guid};
                commands.push({type:"createChild",baseId:baseId,parentId:parameters.parentId,newguid:guid});
                commands.push({type:"modify",id:guid,attributes:attributes});
                self.sendMessage({transactionId:"talan ezt majd hasznaljuk",commands:commands});
            }
            else{
                logger.error("fraudulent child creation: "+JSON.stringify(parameters));
            }
            self.sendMessage({transactionId:"talan ezt majd hasznaljuk",commands:[{type:"createChild",baseId:base,parentId:parent}]});
        };
        this.createSubType = function(parent,base){
            self.sendMessage({transactionId:"talan ezt majd hasznaljuk",commands:[{type:"createSubType",baseId:base,parentId:parent}]});
        };
        this.makePointer = function(id,name,to){
            self.sendMessage({transactionId:"talan ezt majd hasznaljuk",commands:[{type:"point",id:id,to:to,name:name}]});
        };
        this.delPointer = function(id,name){
            self.sendMessage({transactionId:"talan ezt majd hasznaljuk",commands:[{type:"point",id:id,to:null,name:name}]});
        };
        this.makeConnection = function(parameters){
            var commands=[],
                baseId,
                attributes,
                guid;
            if(parameters.parentId && parameters.sourceId && parameters.targetId){
                baseId = parameters.baseId || "connection";
                //guid = commonUtil.guid();
                //TODO: just to make recognisable ID for connection.... delete at some point please
                guid = "conn_" + parameters.sourceId + "_" + parameters.targetId;
                attributes = {name:guid};
                commands.push({type:"createChild",baseId:baseId,parentId:parameters.parentId,newguid:guid});
                commands.push({type:"point",id:guid,name:"source",to:parameters.sourceId});
                commands.push({type:"point",id:guid,name:"target",to:parameters.targetId});
                attributes.directed = parameters.directed;
                commands.push({type:"modify",id:guid,attributes:attributes});
                self.sendMessage({transactionId:"talan ezt majd hasznaljuk",commands:commands});
            }
            else{
                logger.error("fraudulent connection creation: "+JSON.stringify(parameters));
            }
        };

        /*UserInterface handling*/
        this.addUI = function(ui){
            var guid;
            guid = commonUtil.guid();
            users[guid] = new User(self,ui,storage);
            return guid;
        };
        this.removeUI = function(guid){
            delete users[guid];
        };
        this.updateTerritory = function(guid,patterns){
            if(users[guid]){
                users[guid].updatePatterns(patterns);
                self.sendMessage({transactionId:"talan ezt majd hasznaljuk",commands:[{type:"territory",id:guid,patterns:users[guid].getPatterns()}]});
            }
        };

        /*getting a node*/
        this.getNode = function(id){
            if(storage.get(id)){
                return new ClientNode(self,id,storage);
            }
            else{
                return storage.get(id);
            }
        };

        /*socket like functions*/
        this.sendMessage = function(msg){
            socket.emit('clientMessage',msg);
        };
        /*private functions*/
        shootEvent = function(type,id){
            var i,
                data;
            data = storage.get(id);
            for(i in users){
                users[i].shootEvent(id,type);
            }

            if(data && type === "modify"){
                if(data.relations.inheritorIds){
                    for(i=0;i<data.relations.inheritorIds.length;i++){
                        shootEvent(type,data.relations.inheritorIds[i]);
                    }
                }
            }
        };
        handleMessage = function(msg){
            var i;

            /*main*/
            /*if the transaction failed, there is nothing to do*/
            /*for(i=0;i<msg.length;i++){
                if(msg[i].type === "command"){
                    commandqueue.commandResult(msg[i].cid,msg[i].success);
                    if(msg[i].success === "false"){
                        return;
                    }
                }
            }*/

            /*first we shoot the unload events*/
            for(i=0;i<msg.length;i++){
                if(msg[i].type === "unload"){
                    shootEvent("unload",msg[i].id);
                }
            }
            /*then we update the storage*/
            for(i=0;i<msg.length;i++){
                if(msg[i].type !== "command"){
                    storage.set(msg[i].id,msg[i].object);
                }
            }
            /*then we update the users*/
            for(i in users){
                users[i].updateTerritory();
            }
            /*then we shoot all other events*/
            for(i=0;i<msg.length;i++){
                if(msg[i].type === "load" || msg[i].type === "update" || msg[i].type === "create" || msg[i].type === "delete"){
                    shootEvent(msg[i].type,msg[i].id);
                }
            }
        };
    };
    User = function(client,ui,storage){
        var patterns = {},
            ids=[];

        /*public functions*/
        this.getPatterns = function(){
            return patterns;
        };
        this.updatePatterns = function(newpatterns){
            patterns = newpatterns;
        };
        this.shootEvent = function(id,type){
            if(ids.indexOf(id)!== -1){
                ui.onEvent(type,id);
            }
        };
        this.updateTerritory = function(){
            var i,
                updatePattern,
                updateRule;

            updateRule = function(id,rulename,rulevalue,itemssofar){
                var i,
                    data = storage.get(id);

                if(data === null || data === undefined){
                    return;
                }

                if(commonUtil.insertIntoArray(itemssofar,id)){
                    if(rulename === "pointer"){
                        if(rulevalue.value === 0){
                            return;
                        }
                        if(data.pointers[rulevalue.name]){
                            if(data.pointers[rulevalue.name].to){
                                updateRule(data.pointers[rulevalue.name].to,rulename,{name:rulevalue.name,value:rulevalue.value-1},itemssofar);
                            }
                        }
                        return;
                    }
                    else{
                        if(rulevalue === 0){
                            return;
                        }
                        switch(rulename){
                            case "parent":
                                if(data.relations.parentId){
                                    updateRule(data.relations.parentId,rulename,rulevalue-1,itemssofar);
                                }
                                break;
                            case "children":
                                if(data.relations.childrenIds){
                                    for(i=0;i<data.relations.childrenIds.length;i++){
                                        updateRule(data.relations.childrenIds[i],rulename,rulevalue-1,itemssofar);
                                    }
                                }
                                break;
                            case "inheritor":
                                if(data.relations.inheritorIds){
                                    for(i=0;i<data.relations.inheritorIds.length;i++){
                                        updateRule(data.relations.inheritorIds[i],rulename,rulevalue-1,itemssofar);
                                    }
                                }
                                break;
                        }
                    }
                }
                else{
                    return; /*we found a loop*/
                }
            };
            updatePattern = function(id,pattern){
                var i,
                    rulechain;
                for(i in pattern){
                    rulechain = [];
                    updateRule(id,i,commonUtil.copy(pattern[i]),rulechain);
                    ids = commonUtil.mergeArrays(ids,rulechain);
                }
            };
            /*main*/
            ids = [];
            for(i in patterns){
                updatePattern(i,patterns[i]);
            }
        };
    };
    CommandQueue = function(client,storage){
        var queue = {},
            sent = {},
            timer = 10000;
            cansend = true;

        /*public functions*/
        this.push = function(command){
            if(command.type === "territory"){
                /*these can go paralelly without cid*/
                client.sendMessage({commands:[command]});
                return;
            }
            queue[command.cid] = command;
            setTimeout(function(){
                commandTimeout(command.cid);
            },timer);
            sendNextClientMessage();
        };
        this.commandResult = function(cid,success){
            /*TODO success*/
            delete sent[cid];

            if(isSentEmpty()){
                cansend = true;
                sendNextClientMessage();
            }
        };
        var isSentEmpty = function(){
            var counter = 0;
            for(var i in sent){
                counter++;
            }
            if(counter === 0){
                return true;
            }
            return false;
        };
        var sendNextClientMessage = function(){
            logger.debug("trying to send next command message to server (cansend="+cansend+",sentisempty="+isSentEmpty());
            if(cansend ===true || isSentEmpty()){
                cansend = true;
                var msg = {commands:[]};
                for(var i in queue){
                    msg.commands.push(queue[i]);
                }
                logger.debug("next command message to server "+JSON.stringify(msg));
                if(msg.commands.length>0){
                    client.sendMessage(msg);
                    cansend = false;
                    sent = queue;
                    queue = {};
                }
            }
        };
        var commandTimeout = function(cid){
            if(queue[cid] || sent[cid]){
                console.log("command timeout "+cid);
            }
            delete queue[cid];
            delete sent[cid];

            if(isSentEmpty()){
                cansend = true;
                sendNextClientMessage();
            }
        };
    };
    Storage = function(client){
        var objects = {};

        /*public functions*/
        this.get = function(id){
            logger.debug("Storage.get "+id);
            return objects[id];
        };
        this.set = function(id,object){
            logger.debug("Storage.set "+id+","+JSON.stringify(object));
            objects[id] = object;
        };
    };
    ClientNode = function(client,id,storage){
        var selfdata = storage.get(id),
            rGetAttribute,
            rGetRegistry;
        /*public funcitons*/
        this.isDeleted = function(){
            return selfdata === null;
        };
        this.getParentId = function(){
            if(selfdata){
                return selfdata.relations.parentId;
            }
            else{
                return selfdata;
            }
        };
        this.getId = function(){
            if(selfdata){
                return selfdata._id;
            }
            else{
                return selfdata;
            }
        };
        this.getChildrenIds = function(){
            if(selfdata){
                return selfdata.relations.childrenIds;
            }
            else{
                return selfdata;
            }
        };
        this.getBaseId = function(){
            if(selfdata){
                return selfdata.relations.baseId;
            }
            else{
                return selfdata;
            }
        };
        this.getInheritorIds = function(){
            if(selfdata){
                return selfdata.relations.inheritorIds;
            }
            else{
                return selfdata
            }
        };
        this.getAttribute = function(name){
            if(selfdata){
                return rGetAttribute(id,name);
            }
            else{
                return selfdata;
            }
        };
        this.getRegistry = function(name){
            if(selfdata){
                return rGetRegistry(id,name);
            }
            else{
                return selfdata;
            }
        };
        this.getPointer = function(name){
            var pointer = {to:null,from:[]};
            if(selfdata.pointers[name]){
                pointer = commonUtil.copy(selfdata.pointers[name]);
            }
            return pointer;
        };
        this.getConnectionList = function(){
            var i,
                connectionlist = [],
                templist;
            if(selfdata === null || selfdata === undefined){
                return connectionlist;
            }
            if(selfdata.pointers.source){
                templist = commonUtil.copy(selfdata.pointers.source.from);
                for(i=0;i<templist.length;i++){
                    connectionlist.push({id:templist[i],out:true});
                }
            }
            if(selfdata.pointers.target){
                templist = commonUtil.copy(selfdata.pointers.target.from);
                for(i=0;i<templist.length;i++){
                    connectionlist.push({id:templist[i],out:false});
                }
            }
            return connectionlist;
        };
        /*private functions*/
        rGetAttribute = function(id,name){
            var data;
            data = storage.get(id);
            if(data){
                if(data.attributes.hasOwnProperty(name)){
                    return data.attributes[name];
                }
                else{
                    if(data.relations.baseId){
                        return rGetAttribute(data.relations.baseId,name);
                    }
                    else{
                        return null;
                    }
                }
            }
            else{
                return data;
            }
        };
        rGetRegistry = function(id,name){
            var data;
            data = storage.get(id);
            if(data){
                if(data.registry.hasOwnProperty(name)){
                    return data.registry[name];
                }
                else{
                    if(data.relations.baseId){
                        return rGetRegistry(data.relations.baseId,name);
                    }
                    else{
                        return null;
                    }
                }
            }
            else{
                return data;
            }

        };
    };
    return Client;
});
<|endoftext|>


<commit_before>var IdGen = require('./simple-ids');
var _ = require('lodash');
/**
 * @readonly
 * @enum {String}
 * @type {Array}
 */
var eventNames = ['create', 'preupdate', 'update', 'remove'];

function EventBus() {
    var self = this;
    self.subscribers = {};  //TODO use node-hashtable here for better perf
    eventNames.forEach(function (name) {
        self.subscribers[name] = {};
    });

    var methods =  {
        /**
         * @param {eventNames} name
         * @param previousVersion is used with 'preupdate' event, this is the input we got for update, so it can be diffed
         * @this {Mongoose.Document}
         */
        fire: function (name, previousVersion) {
            var evObj = self.subscribers[name];
            for (var i in evObj) {
                evObj[i](this, name, previousVersion);  //stripping away mongoose doc properties, we don't need them for anything
            }
        },
        /**
         * subscribe alias method for subscribing to events
         * @param {String|Array<String>} event
         * @param {Function} callback
         * @returns {*}
         */
        subscribe: function on(event, callback) {
            if (Array.isArray(event)) {
                event.forEach(function (ev) {
                    on(ev, callback);
                });
            } else {
                if(typeof callback == 'function') {
                    var newId = IdGen();
                    self.subscribers[event][newId] = callback;
                    return newId;
                } else {
                    throw new Error('Callback is something else than a function');
                }
            }

        },
        /**
         *
         * @param id
         * @param {String} event
         * @returns {bool}
         */
        unsubscribe: function (id, event) {
            if (event) {
                if (self.subscribers[event][id]) {
                    delete self.subscribers[event][id];
                    return true;
                }
            }
            return false;

        }

    };
    _.extend(this, methods);

}

EventBus.eventNames = eventNames;

module.exports = EventBus;<commit_msg>added TODO<commit_after>var IdGen = require('./simple-ids');
var _ = require('lodash');
/**
 * @readonly
 * @enum {String}
 * @type {Array}
 */
var eventNames = ['create', 'preupdate', 'update', 'remove'];
//TODO rewrite with var EventEmitter = require('events').EventEmitter;
function EventBus() {
    var self = this;
    self.subscribers = {};  //TODO use node-hashtable here for better perf
    eventNames.forEach(function (name) {
        self.subscribers[name] = {};
    });

    var methods =  {
        /**
         * @param {eventNames} name
         * @param previousVersion is used with 'preupdate' event, this is the input we got for update, so it can be diffed
         * @this {Mongoose.Document}
         */
        fire: function (name, previousVersion) {
            var evObj = self.subscribers[name];
            for (var i in evObj) {
                evObj[i](this, name, previousVersion);  //stripping away mongoose doc properties, we don't need them for anything
            }
        },
        /**
         * subscribe alias method for subscribing to events
         * @param {String|Array<String>} event
         * @param {Function} callback
         * @returns {*}
         */
        subscribe: function on(event, callback) {
            if (Array.isArray(event)) {
                event.forEach(function (ev) {
                    on(ev, callback);
                });
            } else {
                if(typeof callback == 'function') {
                    var newId = IdGen();
                    self.subscribers[event][newId] = callback;
                    return newId;
                } else {
                    throw new Error('Callback is something else than a function');
                }
            }

        },
        /**
         *
         * @param id
         * @param {String} event
         * @returns {bool}
         */
        unsubscribe: function (id, event) {
            if (event) {
                if (self.subscribers[event][id]) {
                    delete self.subscribers[event][id];
                    return true;
                }
            }
            return false;

        }

    };
    _.extend(this, methods);

}

EventBus.eventNames = eventNames;

module.exports = EventBus;
<|endoftext|>


<commit_before>/**
 * Class of managing Filtering and displaying of records.
 *
 * @returns {Records}
 */
function Records() {
    /**
     * Object of datatable.
     */
//	this.oTable = null;
    /**
     * URL for managing calls of datatable
     * @type {string}
     */
    var ajaxSource = null;
    var pageUrl = null;
    var selfObj = this;
    var Filters = new Object();
    /**
     * Set the ajax URL of datatable.
     * @param {string} source
     *
     */
    this.setAjaxSource = function (source) {
        ajaxSource = source;

    }
    /**
     * Set the page url.
     * @param {string} url
     *
     */
    this.setPageUrl = function (url) {
        pageUrl = url;

    }
    /**
     * Initialize the datatable.
     *
     */
    this.initDataTable = function () {
        // check the existence of table on which we are going to apply datatable.
        if ($('#records').length > 0)
        {
            // Modify css for managing view.
            $('#container').removeClass('container');
            $('#container').css('margin', '20px');
            oTable =
                    $('#records').dataTable(
                    {
                        "dom": '<"top"p><"clear">tir<"bottom"p>',
                        "bProcessing": true,
                        "bServerSide": true,
                        retrieve: true,
                        destroy: true,
                        "language": {
                            "info": "Showing _START_ - _END_ of _MAX_",
                            "infoFiltered": ''
                        },
                        "aoColumnDefs": [
                            {"bSortable": false, "aTargets": [0]}
                        ],
                        "aaSorting": [],
                        "sAjaxSource": ajaxSource,
                        "bStateSave": true,
//				"fnInitComplete": function () {
//					this.oTable.fnAdjustColumnSizing();
//				},
                        "fnServerData": function (sSource, aoData, fnCallback) {
                            jQuery.getJSON(sSource, aoData, function (json) {
                                fnCallback(json);

                            });
                        },
                    });
        }

    }
    /**
     *
     * @returns {Boolean}
     */
    this.bindEvents = function () {
        $('input[name="mediaType[]"]').click(function () {
            checkParentFacet('media_type', $(this).prop("checked"));
        });
        $('input[name="commercial[]"]').click(function () {
            checkParentFacet('commercial', $(this).prop('checked'));
        });
        $('input[name="format[]"]').click(function () {
            checkParentFacet('format', $(this).prop('checked'));
        });
        $('input[name="base[]"]').click(function () {
            checkParentFacet('base', $(this).prop('checked'));
        });
        $('input[name="recordingStandard[]"]').click(function () {
            checkParentFacet('recordingStandard', $(this).prop('checked'));
        });
        $('input[name="printType[]"]').click(function () {
            checkParentFacet('printType', $(this).prop('checked'));
        });
        $('input[name="project[]"]').click(function () {
            checkParentFacet('project', $(this).prop('checked'));
        });
        $('input[name="reelDiameter[]"]').click(function () {
            checkParentFacet('reelDiameter', $(this).prop('checked'));
        });
        $('input[name="discDiameter[]"]').click(function () {
            checkParentFacet('discDiameter', $(this).prop('checked'));
        });
        $('input[name="acidDetection[]"]').click(function () {
            checkParentFacet('acidDetection', $(this).prop('checked'));
        });
        $('input[name="collectionName[]"]').click(function () {
            checkParentFacet('collectionName', $(this).prop('checked'));
        });
        $('#is_review_check').click(function () {
            var totalChecked = $('#total_checked').val();
            var containerId = $(this).attr('id');
            var currentVal = $('#' + containerId + '_state').val();
            if (currentVal > 0 && totalChecked == 0)
            {
                totalChecked++;
                $('#parent_facet').val(containerId);
                $('#total_checked').val(totalChecked);
            }
            if (currentVal == 0 && $('#parent_facet').val() == containerId) {
                totalChecked--;
                $('#parent_facet').val('');
                $('#total_checked').val(totalChecked);
            }
            filterRecords();
        });

        return true;
    }
    /**
     *
     * @param {type} type
     * @param {type} isChecked
     * @returns {undefined}
     */
    var checkParentFacet = function (type, isChecked) {
        //todo need to update function
        var totalChecked = $('#total_checked').val();
        var total = $('#facet_sidebar input:checked').length;
        console.log(isChecked);
        console.log(total);
        if (total == 0)
            totalChecked = 0;
        if (isChecked == true)
            totalChecked++;
        else
            totalChecked--;

        $('#total_checked').val(totalChecked);

        if ($('#parent_facet').val() == '' && totalChecked == 1)
            $('#parent_facet').val(type);
        else if (totalChecked == 0)
            $('#parent_facet').val('');
        filterRecords();
    }
    /**
     *
     * @returns {undefined}
     */
    var filterRecords = function () {
        $.ajax({
            type: 'GET',
            url: pageUrl,
            data: $('#formSearch').serialize(),
            dataType: 'json',
            success: function (response)
            {
                $("#recordsContainer").html(response.html);
                selfObj.initDataTable();
//                selfObj.bindEvents();
            }

        });
    }
    var customFieldName = 'All';
    var customColumnName = 'all';
    /**
     *
     * @returns {undefined}
     */
    this.addCustomToken = function () {
        $('.customToken').click(function () {
            customFieldName = $(this).attr('data-fieldName');
            customColumnName = $(this).attr('data-columnName');
            $('#limit_field_text').html(customFieldName);
        });
    }

    this.addKeyword = function () {
        $('#addKeyword').click(function () {
            if ($('#keywordSearch').val() != '') {
                if ($('#facet_keyword_search').val() != '' && $('#facet_keyword_search').val() != '""') {
                    Filters = JSON.parse($('#facet_keyword_search').val());
                }
                else {
                    Filters = new Array();
                }
                for (x in Filters) {
                    if (Filters[x].value == $('#keywordSearch').val()) {
                        alert($('#keywordSearch').val() + " filter is already applied.");
                        return false;
                    }
                }
                var temp = {};
                temp.value = $('#keywordSearch').val();
                temp.type = customColumnName;
                Filters.push(temp);

                $('#facet_keyword_search').val(JSON.stringify(Filters));

                filterRecords();
            }
        });
    }
}

<commit_msg>records<commit_after>/**
 * Class of managing Filtering and displaying of records.
 *
 * @returns {Records}
 */
function Records() {
    /**
     * Object of datatable.
     */
//	this.oTable = null;
    /**
     * URL for managing calls of datatable
     * @type {string}
     */
    var ajaxSource = null;
    var pageUrl = null;
    var selfObj = this;
    var Filters = new Object();
    /**
     * Set the ajax URL of datatable.
     * @param {string} source
     *
     */
    this.setAjaxSource = function (source) {
        ajaxSource = source;

    }
    /**
     * Set the page url.
     * @param {string} url
     *
     */
    this.setPageUrl = function (url) {
        pageUrl = url;

    }
    /**
     * Initialize the datatable.
     *
     */
    this.initDataTable = function () {
        // check the existence of table on which we are going to apply datatable.
        if ($('#records').length > 0)
        {
            // Modify css for managing view.
            $('#container').removeClass('container');
            $('#container').css('margin', '20px');
            oTable =
                    $('#records').dataTable(
                    {
                        "dom": '<"top"p><"clear">tir<"bottom"p>',
                        "bProcessing": true,
                        "bServerSide": true,
                        retrieve: true,
                        destroy: true,
                        "language": {
                            "info": "Showing _START_ - _END_ of _MAX_",
                            "infoFiltered": ''
                        },
                        "aoColumnDefs": [
                            {"bSortable": false, "aTargets": [0]}
                        ],
                        "aaSorting": [],
                        "sAjaxSource": ajaxSource,
                        "bStateSave": true,
//				"fnInitComplete": function () {
//					this.oTable.fnAdjustColumnSizing();
//				},
                        "fnServerData": function (sSource, aoData, fnCallback) {
                            jQuery.getJSON(sSource, aoData, function (json) {
                                fnCallback(json);

                            });
                        },
                    });
        }

    }
    /**
     *
     * @returns {Boolean}
     */
    this.bindEvents = function () {
        $('input[name="mediaType[]"]').click(function () {
            checkParentFacet('media_type', $(this).prop("checked"));
        });
        $('input[name="commercial[]"]').click(function () {
            checkParentFacet('commercial', $(this).prop('checked'));
        });
        $('input[name="format[]"]').click(function () {
            checkParentFacet('format', $(this).prop('checked'));
        });
        $('input[name="base[]"]').click(function () {
            checkParentFacet('base', $(this).prop('checked'));
        });
        $('input[name="recordingStandard[]"]').click(function () {
            checkParentFacet('recordingStandard', $(this).prop('checked'));
        });
        $('input[name="printType[]"]').click(function () {
            checkParentFacet('printType', $(this).prop('checked'));
        });
        $('input[name="project[]"]').click(function () {
            checkParentFacet('project', $(this).prop('checked'));
        });
        $('input[name="reelDiameter[]"]').click(function () {
            checkParentFacet('reelDiameter', $(this).prop('checked'));
        });
        $('input[name="discDiameter[]"]').click(function () {
            checkParentFacet('discDiameter', $(this).prop('checked'));
        });
        $('input[name="acidDetection[]"]').click(function () {
            checkParentFacet('acidDetection', $(this).prop('checked'));
        });
        $('input[name="collectionName[]"]').click(function () {
            checkParentFacet('collectionName', $(this).prop('checked'));
        });
        $('#is_review_check').click(function () {
            var totalChecked = $('#total_checked').val();
            var containerId = $(this).attr('id');
            var currentVal = $('#' + containerId + '_state').val();
            if (currentVal > 0 && totalChecked == 0)
            {
                totalChecked++;
                $('#parent_facet').val(containerId);
                $('#total_checked').val(totalChecked);
            }
            if (currentVal == 0 && $('#parent_facet').val() == containerId) {
                totalChecked--;
                $('#parent_facet').val('');
                $('#total_checked').val(totalChecked);
            }
            filterRecords();
        });

        return true;
    }
    /**
     *
     * @param {type} type
     * @param {type} isChecked
     * @returns {undefined}
     */
    var checkParentFacet = function (type, isChecked) {
        //todo need to update function
        var totalChecked = $('#total_checked').val();
        var total = $('#facet_sidebar input:checked').length;
        console.log(isChecked);
        console.log(total);
        if (total == 0)
            totalChecked = 0;
        if (isChecked)
            totalChecked++;
        else
            totalChecked--;

        $('#total_checked').val(totalChecked);

        if ($('#parent_facet').val() == '' && totalChecked == 1)
            $('#parent_facet').val(type);
        else if (totalChecked == 0)
            $('#parent_facet').val('');
        filterRecords();
    }
    /**
     *
     * @returns {undefined}
     */
    var filterRecords = function () {
        $.ajax({
            type: 'GET',
            url: pageUrl,
            data: $('#formSearch').serialize(),
            dataType: 'json',
            success: function (response)
            {
                $("#recordsContainer").html(response.html);
                selfObj.initDataTable();
//                selfObj.bindEvents();
            }

        });
    }
    var customFieldName = 'All';
    var customColumnName = 'all';
    /**
     *
     * @returns {undefined}
     */
    this.addCustomToken = function () {
        $('.customToken').click(function () {
            customFieldName = $(this).attr('data-fieldName');
            customColumnName = $(this).attr('data-columnName');
            $('#limit_field_text').html(customFieldName);
        });
    }

    this.addKeyword = function () {
        $('#addKeyword').click(function () {
            if ($('#keywordSearch').val() != '') {
                if ($('#facet_keyword_search').val() != '' && $('#facet_keyword_search').val() != '""') {
                    Filters = JSON.parse($('#facet_keyword_search').val());
                }
                else {
                    Filters = new Array();
                }
                for (x in Filters) {
                    if (Filters[x].value == $('#keywordSearch').val()) {
                        alert($('#keywordSearch').val() + " filter is already applied.");
                        return false;
                    }
                }
                var temp = {};
                temp.value = $('#keywordSearch').val();
                temp.type = customColumnName;
                Filters.push(temp);

                $('#facet_keyword_search').val(JSON.stringify(Filters));

                filterRecords();
            }
        });
    }
}

<|endoftext|>


<commit_before>var sinon = require('sinon'),
    assert = require('assert'),
    request = require('request-promise'),
    OpenAMClient = require('../lib/openam').OpenAMClient;

describe('Test with private IP', function () {
    var hostname, serverUrl, privateIP;

    beforeEach(function () {

        serverUrl = 'http://openam.example.com:8080/openam';
        hostname = 'openam.example.com';
        privateIP = '127.0.0.1';

        // client instance
        clientIP = new OpenAMClient(serverUrl, privateIP);

        // spies
        getRequests = sinon.spy(request, 'get');
        postRequests = sinon.spy(request, 'post');

    });

    afterEach(function () {
        // restore stubs
        getRequests.restore();
        postRequests.restore();
    });

    describe('getServerInfo', function () {
        it('request should have private ip in url', function () {
            clientIP.getServerInfo();
            assert.equal(request.get.getCall(0).args[0].includes(privateIP), true);
        });
        it('request should have header host value', function () {
            clientIP.getServerInfo();
            assert.equal(request.get.getCall(0).args[1].headers.host, hostname);
        });
    });
    describe('authenticate', function () {
        it('request should have private ip in url', function () {
            clientIP.authenticate();
            assert.equal(request.post.getCall(0).args[0].includes(privateIP), true);
        });
        it('request should have header host value', function () {
            clientIP.authenticate();
            assert.equal(request.post.getCall(0).args[1].headers.host, hostname);
        });
    });
    describe('logout', function () {
        it('request should have private ip in url', function () {
            clientIP.logout('sessionid');
            assert.equal(request.post.getCall(0).args[0].includes(privateIP), true);
        });
        it('request should have header host value', function () {
            clientIP.logout('sessionid');
            assert.equal(request.post.getCall(0).args[1].headers.host, hostname);
        });
    });
    describe('validateSession', function () {
        it('request should have private ip in url', function () {
            clientIP.validateSession('sessionid');
            assert.equal(request.post.getCall(0).args[0].includes(privateIP), true);
        });
        it('request should have header host value', function () {
            clientIP.validateSession('sessionid');
            assert.equal(request.post.getCall(0).args[1].headers.host, hostname);
        });
    });
    describe('getPolicyDecision', function () {
        it('request should have private ip in url', function () {
            clientIP.getPolicyDecision({}, 'sessionId', 'cookieName');
            assert.equal(request.post.getCall(0).args[0].includes(privateIP), true);
        });
        it('request should have header host value', function () {
            clientIP.getPolicyDecision({}, 'sessionId', 'cookieName');
            assert.equal(request.post.getCall(0).args[1].headers.host, hostname);
        });
    });
    describe('sessionServiceRequest', function () {
        it('request should have private ip in url', function () {
            clientIP.sessionServiceRequest();
            assert.equal(request.post.getCall(0).args[0].includes(privateIP), true);
        });
        it('request should have header host value', function () {
            clientIP.sessionServiceRequest();
            assert.equal(request.post.getCall(0).args[1].headers.host, hostname);
        });
    });
    describe('validateAccessToken', function () {
        it('request should have private ip in url', function () {
            clientIP.validateAccessToken();
            assert.equal(request.get.getCall(0).args[0].includes(privateIP), true);
        });
        it('request should have header host value', function () {
            clientIP.validateAccessToken();
            assert.equal(request.get.getCall(0).args[1].headers.host, hostname);
        });
    });
    describe('getProfile', function () {
        it('request should have private ip in url', function () {
            clientIP.getProfile();
            assert.equal(request.get.getCall(0).args[0].includes(privateIP), true);
        });
        it('request should have header host value', function () {
            clientIP.getProfile();
            assert.equal(request.get.getCall(0).args[1].headers.host, hostname);
        });
    });
});
describe('Test without private IP', function () {
    var serverUrl;

    beforeEach(function () {

        serverUrl = 'http://openam.example.com:8080/openam';

        // client instance
        client = new OpenAMClient(serverUrl);

        // spies
        getRequests = sinon.spy(request, 'get');
        postRequests = sinon.spy(request, 'post');

    });

    afterEach(function () {
        // restore stubs
        getRequests.restore();
        postRequests.restore();
    });

    describe('getServerInfo', function () {
        it('request should have serverUrl in url', function () {
            client.getServerInfo();
            assert.equal(request.get.getCall(0).args[0].includes(serverUrl), true);
        });
        it('request should not have header host value', function () {
            client.getServerInfo();
            assert.equal(request.get.getCall(0).args[1].headers.host, undefined);
        });
    });
    describe('authenticate', function () {
        it('request should have serverUrl in url', function () {
            client.authenticate();
            assert.equal(request.post.getCall(0).args[0].includes(serverUrl), true);
        });
        it('request should not have header host value', function () {
            client.authenticate();
            assert.equal(request.post.getCall(0).args[1].headers.host, undefined);
        });
    });
    describe('logout', function () {
        it('request should not have serverUrl in url', function () {
            client.logout('sessionid');
            assert.equal(request.post.getCall(0).args[0].includes(serverUrl), true);
        });
        it('request should not have header host value', function () {
            client.logout('sessionid');
            assert.equal(request.post.getCall(0).args[1].headers.host, undefined);
        });
    });
    describe('validateSession', function () {
        it('request should not have serverUrl in url', function () {
            client.validateSession('sessionid');
            assert.equal(request.post.getCall(0).args[0].includes(serverUrl), true);
        });
        it('request should not have header host value', function () {
            client.validateSession('sessionid');
            assert.equal(request.post.getCall(0).args[1].headers.host, undefined);
        });
    });
    describe('getPolicyDecision', function () {
        it('request should not have serverUrl in url', function () {
            client.getPolicyDecision({}, 'sessionID', 'cookieName');
            assert.equal(request.post.getCall(0).args[0].includes(serverUrl), true);
        });
        it('request should not have header host value', function () {
            client.getPolicyDecision({}, 'sessionID', 'cookieName');
            assert.equal(request.post.getCall(0).args[1].headers.host, undefined);
        });
    });
    describe('sessionServiceRequest', function () {
        it('request should not have serverUrl in url', function () {
            client.sessionServiceRequest();
            assert.equal(request.post.getCall(0).args[0].includes(serverUrl), true);
        });
        it('request should not have header host value', function () {
            client.sessionServiceRequest();
            assert.equal(request.post.getCall(0).args[1].headers.host, undefined);
        });
    });
    describe('validateAccessToken', function () {
        it('request should have serverUrl in url', function () {
            client.validateAccessToken();
            assert.equal(request.get.getCall(0).args[0].includes(serverUrl), true);
        });
        it('request should not have header host value', function () {
            client.validateAccessToken();
            assert.equal(request.get.getCall(0).args[1].headers.host, undefined);
        });
    });
    describe('getProfile', function () {
        it('request should have serverUrl in url', function () {
            client.getProfile();
            assert.equal(request.get.getCall(0).args[0].includes(serverUrl), true);
        });
        it('request should not have header host value', function () {
            client.getProfile();
            assert.equal(request.get.getCall(0).args[1].headers.host, undefined);
        });
    });
});<commit_msg>changed methods for testing if url contains substring<commit_after>var sinon = require('sinon'),
    assert = require('assert'),
    request = require('request-promise'),
    OpenAMClient = require('../lib/openam').OpenAMClient;

describe('Test with private IP', function () {
    var hostname, serverUrl, privateIP;

    beforeEach(function () {

        serverUrl = 'http://openam.example.com:8080/openam';
        hostname = 'openam.example.com';
        privateIP = '127.0.0.1';

        // client instance
        clientIP = new OpenAMClient(serverUrl, privateIP);

        // spies
        getRequests = sinon.spy(request, 'get');
        postRequests = sinon.spy(request, 'post');

    });

    afterEach(function () {
        // restore stubs
        getRequests.restore();
        postRequests.restore();
    });

    describe('getServerInfo', function () {
        it('request should have private ip in url', function () {
            clientIP.getServerInfo();
            assert.equal((request.get.getCall(0).args[0].indexOf(privateIP) > -1), true);
        });
        it('request should have header host value', function () {
            clientIP.getServerInfo();
            assert.equal(request.get.getCall(0).args[1].headers.host, hostname);
        });
    });
    describe('authenticate', function () {
        it('request should have private ip in url', function () {
            clientIP.authenticate();
            assert.equal((request.post.getCall(0).args[0].indexOf(privateIP) > -1), true);
        });
        it('request should have header host value', function () {
            clientIP.authenticate();
            assert.equal(request.post.getCall(0).args[1].headers.host, hostname);
        });
    });
    describe('logout', function () {
        it('request should have private ip in url', function () {
            clientIP.logout('sessionid');
            assert.equal((request.post.getCall(0).args[0].indexOf(privateIP) > -1), true);
        });
        it('request should have header host value', function () {
            clientIP.logout('sessionid');
            assert.equal(request.post.getCall(0).args[1].headers.host, hostname);
        });
    });
    describe('validateSession', function () {
        it('request should have private ip in url', function () {
            clientIP.validateSession('sessionid');
            assert.equal((request.post.getCall(0).args[0].indexOf(privateIP) > -1), true);
        });
        it('request should have header host value', function () {
            clientIP.validateSession('sessionid');
            assert.equal(request.post.getCall(0).args[1].headers.host, hostname);
        });
    });
    describe('getPolicyDecision', function () {
        it('request should have private ip in url', function () {
            clientIP.getPolicyDecision({}, 'sessionId', 'cookieName');
            assert.equal((request.post.getCall(0).args[0].indexOf(privateIP) > -1), true);
        });
        it('request should have header host value', function () {
            clientIP.getPolicyDecision({}, 'sessionId', 'cookieName');
            assert.equal(request.post.getCall(0).args[1].headers.host, hostname);
        });
    });
    describe('sessionServiceRequest', function () {
        it('request should have private ip in url', function () {
            clientIP.sessionServiceRequest();
            assert.equal((request.post.getCall(0).args[0].indexOf(privateIP) > -1), true);
        });
        it('request should have header host value', function () {
            clientIP.sessionServiceRequest();
            assert.equal(request.post.getCall(0).args[1].headers.host, hostname);
        });
    });
    describe('validateAccessToken', function () {
        it('request should have private ip in url', function () {
            clientIP.validateAccessToken();
            assert.equal((request.get.getCall(0).args[0].indexOf(privateIP) > -1), true);
        });
        it('request should have header host value', function () {
            clientIP.validateAccessToken();
            assert.equal(request.get.getCall(0).args[1].headers.host, hostname);
        });
    });
    describe('getProfile', function () {
        it('request should have private ip in url', function () {
            clientIP.getProfile();
            assert.equal((request.get.getCall(0).args[0].indexOf(privateIP) > -1), true);
        });
        it('request should have header host value', function () {
            clientIP.getProfile();
            assert.equal(request.get.getCall(0).args[1].headers.host, hostname);
        });
    });
});
describe('Test without private IP', function () {
    var serverUrl;

    beforeEach(function () {

        serverUrl = 'http://openam.example.com:8080/openam';

        // client instance
        client = new OpenAMClient(serverUrl);

        // spies
        getRequests = sinon.spy(request, 'get');
        postRequests = sinon.spy(request, 'post');

    });

    afterEach(function () {
        // restore stubs
        getRequests.restore();
        postRequests.restore();
    });

    describe('getServerInfo', function () {
        it('request should have serverUrl in url', function () {
            client.getServerInfo();
            assert.equal((request.get.getCall(0).args[0].indexOf(serverUrl) > -1), true);
        });
        it('request should not have header host value', function () {
            client.getServerInfo();
            assert.equal(request.get.getCall(0).args[1].headers.host, undefined);
        });
    });
    describe('authenticate', function () {
        it('request should have serverUrl in url', function () {
            client.authenticate();
            assert.equal((request.post.getCall(0).args[0].indexOf(serverUrl) > -1), true);
        });
        it('request should not have header host value', function () {
            client.authenticate();
            assert.equal(request.post.getCall(0).args[1].headers.host, undefined);
        });
    });
    describe('logout', function () {
        it('request should not have serverUrl in url', function () {
            client.logout('sessionid');
            assert.equal((request.post.getCall(0).args[0].indexOf(serverUrl) > -1), true);
        });
        it('request should not have header host value', function () {
            client.logout('sessionid');
            assert.equal(request.post.getCall(0).args[1].headers.host, undefined);
        });
    });
    describe('validateSession', function () {
        it('request should not have serverUrl in url', function () {
            client.validateSession('sessionid');
            assert.equal((request.post.getCall(0).args[0].indexOf(serverUrl) > -1), true);
        });
        it('request should not have header host value', function () {
            client.validateSession('sessionid');
            assert.equal(request.post.getCall(0).args[1].headers.host, undefined);
        });
    });
    describe('getPolicyDecision', function () {
        it('request should not have serverUrl in url', function () {
            client.getPolicyDecision({}, 'sessionID', 'cookieName');
            assert.equal((request.post.getCall(0).args[0].indexOf(serverUrl) > -1), true);
        });
        it('request should not have header host value', function () {
            client.getPolicyDecision({}, 'sessionID', 'cookieName');
            assert.equal(request.post.getCall(0).args[1].headers.host, undefined);
        });
    });
    describe('sessionServiceRequest', function () {
        it('request should not have serverUrl in url', function () {
            client.sessionServiceRequest();
            assert.equal((request.post.getCall(0).args[0].indexOf(serverUrl) > -1), true);
        });
        it('request should not have header host value', function () {
            client.sessionServiceRequest();
            assert.equal(request.post.getCall(0).args[1].headers.host, undefined);
        });
    });
    describe('validateAccessToken', function () {
        it('request should have serverUrl in url', function () {
            client.validateAccessToken();
            assert.equal((request.get.getCall(0).args[0].indexOf(serverUrl) > -1), true);
        });
        it('request should not have header host value', function () {
            client.validateAccessToken();
            assert.equal(request.get.getCall(0).args[1].headers.host, undefined);
        });
    });
    describe('getProfile', function () {
        it('request should have serverUrl in url', function () {
            client.getProfile();
            assert.equal((request.get.getCall(0).args[0].indexOf(serverUrl) > -1), true);
        });
        it('request should not have header host value', function () {
            client.getProfile();
            assert.equal(request.get.getCall(0).args[1].headers.host, undefined);
        });
    });
});<|endoftext|>


<commit_before>// Queue design document
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

require('defaultable')(module,
  {
  }, function(module, exports, DEFS, require) {

var fs = require('fs')
  , lib = require('./lib')
  , path = require('path')
  , util = require('util')
  , assert = require('assert')
  ;

module.exports = { "DDoc" : DDoc

                 // For importing and unit testing.
                 , 'validate_doc_update': validate_doc_update
                 , 'visible_at'         : visible_at
                 , 'enqueue_message'    : enqueue_message
                 }

//
// Constants
//

var TEMPLATE =
  // _id
  // _rev
{ 'queues': {}

, updates: {"queue": enqueue_message}
, views: { "visible_at": { map: visible_at
                         , reduce: '_count'
                         }
         }

, "validate_doc_update": validate_doc_update
}

function enqueue_message(doc, req) {
  if(req.method != 'POST')
    return resp(400, {'error':'Only POST is allowed'})

  if(doc)
    return resp(400, {'error':'Only creating new messages is allowed'})

  try {
    var body = JSON.parse(req.body)
  } catch (er) {
    return resp(400, {'error':'Bad JSON body'})
  }

  // Figure out the queue to update, from .../_update/this_function/queue_name
  var i = req.path.indexOf('_update')
  var queue = req.path[i+2]

  var now = new Date
  doc =
    { _id: 'CQS/' + queue + '/' + req.uuid
    , ApproximateFirstReceiveTimestamp: null
    , ApproximateReceiveCount         : 0
    , Body                            : body
    , SenderId                        : req.userCtx.name
    , SentTimestamp                   : now
    , visible_at                      : now
    }

  //log('Create CQS document: ' + JSON.stringify(doc))
  return resp(201, doc)

  function resp(code, body) {
    if(code != 201)
      doc = null

    return [doc,
      { 'code'   : code
      , 'headers': {'content-type':'application/json'}
      , 'body'   : JSON.stringify(body) + "\n"
      }
    ]
  }
}

function validate_doc_update(newDoc, oldDoc, userCtx, secObj) {
  var ddoc = this
  var msg_id_re = /^CQS\/(.+?)\/([0-9a-f]{32})($|\/(.*)$)/

  var match = newDoc._id.match(msg_id_re)
  if(!match && ddoc.allow_foreign_docs)
    return // Ignore this non-CQS document.
  if(!match)
    throw {'forbidden': 'This database is for CQS only; bad message ID: ' + newDoc._id}

  var queue_id = match[1]
    , msg_id   = match[2]

  if(! (queue_id in ddoc.queues))
    throw {'forbidden':'Queue does not exist: '+queue_id}

  var IS_DB_ADMIN = false;

  secObj.admins = secObj.admins || {};
  secObj.admins.names = secObj.admins.names || [];
  secObj.admins.roles = secObj.admins.roles || [];

  if(userCtx.roles.indexOf('_admin') !== -1)
    IS_DB_ADMIN = true;
  if(secObj.admins.names.indexOf(userCtx.name) !== -1)
    IS_DB_ADMIN = true;
  for(i = 0; i < userCtx.roles; i++)
    if(secObj.admins.roles.indexOf(userCtx.roles[i]) !== -1)
      IS_DB_ADMIN = true;

  var good_keys = [ "_id", "_rev", "_revisions", "_deleted"
                  , 'SenderId'
                  , 'SentTimestamp'
                  , 'visible_at'
                  , 'ApproximateReceiveCount'
                  , 'ApproximateFirstReceiveTimestamp'
                  , 'MD5OfMessageBody'
                  , 'Body'

                  // Some extensions
                  , 'ReceiverId'
                  ];

  var key;
  for (key in newDoc)
    if(good_keys.indexOf(key) === -1)
      throw({forbidden: "Invalid field: " + key});

  if(! newDoc._deleted) {
    if(newDoc.Body === null || newDoc.Body === undefined)
      throw {forbidden: 'Invalid .Body: ' + JSON.stringify(newDoc.Body)};
  } else {
    if(!oldDoc || oldDoc.ReceiverId !== userCtx.name) {
      if(IS_DB_ADMIN)
        log('Allowing db admin "'+userCtx.name+'" to delete: ' + newDoc._id);
      else
        throw {forbidden: 'You may not delete this document'};
    }

    return;
  }

  if(!newDoc.visible_at)
    throw {forbidden: 'Must set visible_at'};

  if(oldDoc) {
    // Checkout ("receive")
    if(newDoc.ReceiverId !== userCtx.name && !IS_DB_ADMIN)
      throw({forbidden: 'Must set ReceiverId to your name: ' + JSON.stringify(userCtx.name)});

  } else {
    // Message send
    if(newDoc.SenderId !== userCtx.name && !IS_DB_ADMIN)
      throw({forbidden: 'Must set SenderId to your name: ' + JSON.stringify(userCtx.name)});
  }
}

function visible_at(doc) {
  var msg_id_re = /^CQS\/(.+?)\/([0-9a-f]{32})($|\/(.*)$)/

  var match = doc._id.match(msg_id_re)
  if(!match || !doc.visible_at)
    return

  var queue_id = match[1]
    , msg_id   = match[2]

  // The client must be able to check out ("receive") the message using this view data,
  // which means MVCC stuff and anything else necessary.
  var val = {"_id":doc._id, "_rev":doc._rev};
  for(var a in doc)
    if(a.match(/^[A-Z]/))
      val[a] = doc[a]

  var key = [queue_id, doc.visible_at]
  emit(key, val)
}

//
// API
//

function DDoc () {
  var self = this;

  self.copy_template();

  self._id = "_design/cqs"
}

// One common logger for them all, just so it won't get stored in couch.
DDoc.prototype.log = lib.log4js.getLogger('ddoc');
DDoc.prototype.log.setLevel(lib.LOG_LEVEL);

DDoc.prototype.copy_template = function() {
  var self = this;

//  if(self.name.length < 1 || self.name.length > 80)
//    throw new Error("Queue name exceeds length max of 80: " + self.name.length)

  var ddoc = templated_ddoc()
  lib.copy(ddoc, self);
}

// Attach the web browser port.
DDoc.prototype.add_browser = function(callback) {
  var counter = 0

  this._attachments = this._attachments || {};

  ;['cqs.min.js', 'showlist.js', 'index.html']
  .forEach(function(name) {
    counter++

    fs.readFile(__dirname + '/browser/' + name, function(err, code) {
      if(err) {
        counter = -1
        return callback(err)
      }

      this._attachments[name] = { content_type: name.substr(-3) === '.js' ? 'text/javascript' : 'text/html'
                                , data         : code.toString('base64')
                                }

      if(!--counter)
        callback()
    })
  })
}

//
// Utilities
//

function templated_ddoc(name) {
  return stringify_functions(TEMPLATE)
  function stringify_functions(obj) {
    var copy = {};

    if(Array.isArray(obj))
      return obj.map(stringify_functions)

    else if(typeof obj === 'object' && obj !== null) {
      Object.keys(obj).forEach(function(key) {
        copy[key] = stringify_functions(obj[key]);
      })
      return copy;
    }

    else if(typeof obj === 'function')
      return func_from_template(obj)

    else
      return lib.JDUP(obj);
  }
}

function func_from_template(func) {
  var src = func.toString();
  src = src.replace(/^function.*?\(/, 'function (');
  return src;
}

}) // defaultable
<commit_msg>added `self` reference in DDoc#add_browser<commit_after>// Queue design document
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

require('defaultable')(module,
  {
  }, function(module, exports, DEFS, require) {

var fs = require('fs')
  , lib = require('./lib')
  , path = require('path')
  , util = require('util')
  , assert = require('assert')
  ;

module.exports = { "DDoc" : DDoc

                 // For importing and unit testing.
                 , 'validate_doc_update': validate_doc_update
                 , 'visible_at'         : visible_at
                 , 'enqueue_message'    : enqueue_message
                 }

//
// Constants
//

var TEMPLATE =
  // _id
  // _rev
{ 'queues': {}

, updates: {"queue": enqueue_message}
, views: { "visible_at": { map: visible_at
                         , reduce: '_count'
                         }
         }

, "validate_doc_update": validate_doc_update
}

function enqueue_message(doc, req) {
  if(req.method != 'POST')
    return resp(400, {'error':'Only POST is allowed'})

  if(doc)
    return resp(400, {'error':'Only creating new messages is allowed'})

  try {
    var body = JSON.parse(req.body)
  } catch (er) {
    return resp(400, {'error':'Bad JSON body'})
  }

  // Figure out the queue to update, from .../_update/this_function/queue_name
  var i = req.path.indexOf('_update')
  var queue = req.path[i+2]

  var now = new Date
  doc =
    { _id: 'CQS/' + queue + '/' + req.uuid
    , ApproximateFirstReceiveTimestamp: null
    , ApproximateReceiveCount         : 0
    , Body                            : body
    , SenderId                        : req.userCtx.name
    , SentTimestamp                   : now
    , visible_at                      : now
    }

  //log('Create CQS document: ' + JSON.stringify(doc))
  return resp(201, doc)

  function resp(code, body) {
    if(code != 201)
      doc = null

    return [doc,
      { 'code'   : code
      , 'headers': {'content-type':'application/json'}
      , 'body'   : JSON.stringify(body) + "\n"
      }
    ]
  }
}

function validate_doc_update(newDoc, oldDoc, userCtx, secObj) {
  var ddoc = this
  var msg_id_re = /^CQS\/(.+?)\/([0-9a-f]{32})($|\/(.*)$)/

  var match = newDoc._id.match(msg_id_re)
  if(!match && ddoc.allow_foreign_docs)
    return // Ignore this non-CQS document.
  if(!match)
    throw {'forbidden': 'This database is for CQS only; bad message ID: ' + newDoc._id}

  var queue_id = match[1]
    , msg_id   = match[2]

  if(! (queue_id in ddoc.queues))
    throw {'forbidden':'Queue does not exist: '+queue_id}

  var IS_DB_ADMIN = false;

  secObj.admins = secObj.admins || {};
  secObj.admins.names = secObj.admins.names || [];
  secObj.admins.roles = secObj.admins.roles || [];

  if(userCtx.roles.indexOf('_admin') !== -1)
    IS_DB_ADMIN = true;
  if(secObj.admins.names.indexOf(userCtx.name) !== -1)
    IS_DB_ADMIN = true;
  for(i = 0; i < userCtx.roles; i++)
    if(secObj.admins.roles.indexOf(userCtx.roles[i]) !== -1)
      IS_DB_ADMIN = true;

  var good_keys = [ "_id", "_rev", "_revisions", "_deleted"
                  , 'SenderId'
                  , 'SentTimestamp'
                  , 'visible_at'
                  , 'ApproximateReceiveCount'
                  , 'ApproximateFirstReceiveTimestamp'
                  , 'MD5OfMessageBody'
                  , 'Body'

                  // Some extensions
                  , 'ReceiverId'
                  ];

  var key;
  for (key in newDoc)
    if(good_keys.indexOf(key) === -1)
      throw({forbidden: "Invalid field: " + key});

  if(! newDoc._deleted) {
    if(newDoc.Body === null || newDoc.Body === undefined)
      throw {forbidden: 'Invalid .Body: ' + JSON.stringify(newDoc.Body)};
  } else {
    if(!oldDoc || oldDoc.ReceiverId !== userCtx.name) {
      if(IS_DB_ADMIN)
        log('Allowing db admin "'+userCtx.name+'" to delete: ' + newDoc._id);
      else
        throw {forbidden: 'You may not delete this document'};
    }

    return;
  }

  if(!newDoc.visible_at)
    throw {forbidden: 'Must set visible_at'};

  if(oldDoc) {
    // Checkout ("receive")
    if(newDoc.ReceiverId !== userCtx.name && !IS_DB_ADMIN)
      throw({forbidden: 'Must set ReceiverId to your name: ' + JSON.stringify(userCtx.name)});

  } else {
    // Message send
    if(newDoc.SenderId !== userCtx.name && !IS_DB_ADMIN)
      throw({forbidden: 'Must set SenderId to your name: ' + JSON.stringify(userCtx.name)});
  }
}

function visible_at(doc) {
  var msg_id_re = /^CQS\/(.+?)\/([0-9a-f]{32})($|\/(.*)$)/

  var match = doc._id.match(msg_id_re)
  if(!match || !doc.visible_at)
    return

  var queue_id = match[1]
    , msg_id   = match[2]

  // The client must be able to check out ("receive") the message using this view data,
  // which means MVCC stuff and anything else necessary.
  var val = {"_id":doc._id, "_rev":doc._rev};
  for(var a in doc)
    if(a.match(/^[A-Z]/))
      val[a] = doc[a]

  var key = [queue_id, doc.visible_at]
  emit(key, val)
}

//
// API
//

function DDoc () {
  var self = this;

  self.copy_template();

  self._id = "_design/cqs"
}

// One common logger for them all, just so it won't get stored in couch.
DDoc.prototype.log = lib.log4js.getLogger('ddoc');
DDoc.prototype.log.setLevel(lib.LOG_LEVEL);

DDoc.prototype.copy_template = function() {
  var self = this;

//  if(self.name.length < 1 || self.name.length > 80)
//    throw new Error("Queue name exceeds length max of 80: " + self.name.length)

  var ddoc = templated_ddoc()
  lib.copy(ddoc, self);
}

// Attach the web browser port.
DDoc.prototype.add_browser = function(callback) {
  var counter = 0
    , self = this

  this._attachments = this._attachments || {}

  ;['cqs.min.js', 'showlist.js', 'index.html']
  .forEach(function(name) {
    counter++

    fs.readFile(__dirname + '/browser/' + name, function(err, code) {
      if(err) {
        counter = -1
        return callback(err)
      }

      this._attachments[name] = { content_type: name.substr(-3) === '.js' ? 'text/javascript' : 'text/html'
                                , data         : code.toString('base64')
                                }

      if(!--counter)
        callback()
    })
  })
}

//
// Utilities
//

function templated_ddoc(name) {
  return stringify_functions(TEMPLATE)
  function stringify_functions(obj) {
    var copy = {};

    if(Array.isArray(obj))
      return obj.map(stringify_functions)

    else if(typeof obj === 'object' && obj !== null) {
      Object.keys(obj).forEach(function(key) {
        copy[key] = stringify_functions(obj[key]);
      })
      return copy;
    }

    else if(typeof obj === 'function')
      return func_from_template(obj)

    else
      return lib.JDUP(obj);
  }
}

function func_from_template(func) {
  var src = func.toString();
  src = src.replace(/^function.*?\(/, 'function (');
  return src;
}

}) // defaultable
<|endoftext|>


<commit_before>/* global d3 */
var url = hqImport('hqwebapp/js/initial_page_data').reverse;

function FunctionalToiletController($scope, $routeParams, $location, $filter, infrastructureService,
    locationsService, dateHelperService, navigationService, userLocationId, storageService,
    haveAccessToAllLocations, baseControllersService, isAlertActive) {
    baseControllersService.BaseController.call(this, $scope, $routeParams, $location, locationsService,
        dateHelperService, navigationService, userLocationId, storageService, haveAccessToAllLocations);
    var vm = this;
    vm.isAlertActive = isAlertActive;
    vm.label = "AWCs Reported Functional Toilet";
    vm.steps = {
        'map': {route: '/awc_infrastructure/functional_toilet/map', label: 'Map View'},
        'chart': {route: '/awc_infrastructure/functional_toilet/chart', label: 'Chart View'},
    };
    vm.data = {
        legendTitle: 'Percentage',
    };
    vm.filters = ['gender', 'age'];
    vm.rightLegend = {
        info: 'Of the AWCs that submitted an Infrastructure Details form, the percentage of AWCs that reported having a functional toilet',
    };

    vm.templatePopup = function(loc, row) {
        var inMonth = row ? $filter('indiaNumbers')(row.in_month) : 'N/A';
        var percent = row ? d3.format('.2%')(row.in_month / (row.all || 1)) : "N/A";
        return vm.createTemplatePopup(
            loc.properties.name,
            [{
                indicator_name: 'Number of AWCs that reported having a functional toilet: ',
                indicator_value: inMonth,
            },
            {
                indicator_name: '% of AWCs that reported having a functional toilet: ',
                indicator_value: percent,
            }]
        );
    };

    vm.loadData = function () {
        vm.setStepsMapLabel();
        var usePercentage = true;
        var forceYAxisFromZero = false;
        vm.myPromise = infrastructureService.getFunctionalToiletData(vm.step, vm.filtersData).then(
            vm.loadDataFromResponse(usePercentage, forceYAxisFromZero)
        );
    };

    vm.init();

    var options = {
        'xAxisTickFormat': '%b %Y',
        'yAxisTickFormat': ".2%",
        'captionContent': ' Of the AWCs that submitted an Infrastructure Details form, the percentage of AWCs that reported having a functional toilet',
    };
    vm.chartOptions = vm.getChartOptions(options);
    vm.chartOptions.chart.color = d3.scale.category10().range();

    vm.tooltipContent = function (monthName, dataInMonth) {
        return vm.createTooltipContent(
            monthName,
            [{
                indicator_name: 'Number of AWCs that reported having a functional toilet: ',
                indicator_value: $filter('indiaNumbers')(dataInMonth.in_month),
            },
            {
                indicator_name: '% of AWCs that reported having a functional toilet: ',
                indicator_value: d3.format('.2%')(dataInMonth.y),
            }]
        );
    };
}

FunctionalToiletController.$inject = [
    '$scope', '$routeParams', '$location', '$filter',
    'infrastructureService', 'locationsService', 'dateHelperService', 'navigationService', 'userLocationId',
    'storageService', 'haveAccessToAllLocations', 'baseControllersService', 'isAlertActive'
];

window.angular.module('icdsApp').directive('functionalToilet', function() {
    return {
        restrict: 'E',
        templateUrl: url('icds-ng-template', 'map-chart'),
        bindToController: true,
        scope: {
            data: '=',
        },
        controller: FunctionalToiletController,
        controllerAs: '$ctrl',
    };
});
<commit_msg>port functional toilet report to mobile<commit_after>/* global d3 */
var url = hqImport('hqwebapp/js/initial_page_data').reverse;

function FunctionalToiletController($scope, $routeParams, $location, $filter, infrastructureService,
    locationsService, dateHelperService, navigationService, userLocationId, storageService,
    haveAccessToAllLocations, baseControllersService, isAlertActive, isMobile) {
    baseControllersService.BaseController.call(this, $scope, $routeParams, $location, locationsService,
        dateHelperService, navigationService, userLocationId, storageService, haveAccessToAllLocations,
        false, isMobile);
    var vm = this;
    vm.isAlertActive = isAlertActive;
    vm.label = "AWCs Reported Functional Toilet";
    vm.serviceDataFunction = infrastructureService.getFunctionalToiletData;
    vm.steps = {
        'map': {route: '/awc_infrastructure/functional_toilet/map', label: 'Map View'},
        'chart': {route: '/awc_infrastructure/functional_toilet/chart', label: 'Chart View'},
    };
    vm.data = {
        legendTitle: 'Percentage',
    };
    vm.filters = ['gender', 'age'];
    vm.rightLegend = {
        info: 'Of the AWCs that submitted an Infrastructure Details form, the percentage of AWCs that reported having a functional toilet',
    };

    vm.getPopupData = function (row) {
        var inMonth = row ? $filter('indiaNumbers')(row.in_month) : 'N/A';
        var percent = row ? d3.format('.2%')(row.in_month / (row.all || 1)) : "N/A";
        return [
            {
                indicator_name: 'Number of AWCs that reported having a functional toilet: ',
                indicator_value: inMonth,
            },
            {
                indicator_name: '% of AWCs that reported having a functional toilet: ',
                indicator_value: percent,
            }
        ];
    };

    vm.init();

    var options = {
        'xAxisTickFormat': '%b %Y',
        'yAxisTickFormat': ".2%",
        'captionContent': ' Of the AWCs that submitted an Infrastructure Details form, the percentage of AWCs that reported having a functional toilet',
    };
    vm.chartOptions = vm.getChartOptions(options);
    vm.chartOptions.chart.color = d3.scale.category10().range();

    vm.tooltipContent = function (monthName, dataInMonth) {
        return vm.createTooltipContent(
            monthName,
            [{
                indicator_name: 'Number of AWCs that reported having a functional toilet: ',
                indicator_value: $filter('indiaNumbers')(dataInMonth.in_month),
            },
            {
                indicator_name: '% of AWCs that reported having a functional toilet: ',
                indicator_value: d3.format('.2%')(dataInMonth.y),
            }]
        );
    };
}

FunctionalToiletController.$inject = [
    '$scope', '$routeParams', '$location', '$filter',
    'infrastructureService', 'locationsService', 'dateHelperService', 'navigationService', 'userLocationId',
    'storageService', 'haveAccessToAllLocations', 'baseControllersService', 'isAlertActive', 'isMobile',
];

window.angular.module('icdsApp').directive('functionalToilet', ['templateProviderService', function (templateProviderService) {
    return {
        restrict: 'E',
        templateUrl: templateProviderService.getMapChartTemplate,
        bindToController: true,
        scope: {
            data: '=',
        },
        controller: FunctionalToiletController,
        controllerAs: '$ctrl',
    };
}]);
<|endoftext|>